diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2014-05-20 17:36:55 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2014-05-20 21:22:56 +0200 |
commit | 6af08cecc609d8cfd7e59338398a37cc954828b7 (patch) | |
tree | ef3ff1cba93c8e4d84e866897c66981d248fcd39 | |
parent | 4c3a69653fcc9293f62f7382d51303e2e7f55338 (diff) | |
download | sonarqube-6af08cecc609d8cfd7e59338398a37cc954828b7.tar.gz sonarqube-6af08cecc609d8cfd7e59338398a37cc954828b7.zip |
SONAR-5007 improve conversion fk of ES doc to WS response
50 files changed, 956 insertions, 558 deletions
diff --git a/sonar-core/src/test/java/org/sonar/core/rule/RuleDaoTest.java b/sonar-core/src/test/java/org/sonar/core/rule/RuleDaoTest.java index 8b0c63095db..1cafd982568 100644 --- a/sonar-core/src/test/java/org/sonar/core/rule/RuleDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/rule/RuleDaoTest.java @@ -29,6 +29,7 @@ import org.junit.Test; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; import org.sonar.api.rules.Rule; +import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.utils.DateUtils; import org.sonar.check.Cardinality; import org.sonar.core.persistence.AbstractDaoTestCase; @@ -187,8 +188,8 @@ public class RuleDaoTest extends AbstractDaoTestCase { .setNoteUpdatedAt(DateUtils.parseDate("2013-12-20")) .setSubCharacteristicId(100) .setDefaultSubCharacteristicId(101) - .setRemediationFunction("linear") - .setDefaultRemediationFunction("linear_offset") + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("1h") .setDefaultRemediationCoefficient("5d") .setRemediationOffset("5min") @@ -220,8 +221,8 @@ public class RuleDaoTest extends AbstractDaoTestCase { .setParentId(3) .setSubCharacteristicId(100) .setDefaultSubCharacteristicId(101) - .setRemediationFunction("linear") - .setDefaultRemediationFunction("linear_offset") + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("1h") .setDefaultRemediationCoefficient("5d") .setRemediationOffset("5min") @@ -253,8 +254,8 @@ public class RuleDaoTest extends AbstractDaoTestCase { .setParentId(3) .setSubCharacteristicId(100) .setDefaultSubCharacteristicId(101) - .setRemediationFunction("linear") - .setDefaultRemediationFunction("linear_offset") + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("1h") .setDefaultRemediationCoefficient("5d") .setRemediationOffset("5min") @@ -275,8 +276,8 @@ public class RuleDaoTest extends AbstractDaoTestCase { .setParentId(null) .setSubCharacteristicId(102) .setDefaultSubCharacteristicId(103) - .setRemediationFunction("linear_offset") - .setDefaultRemediationFunction("linear") + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) .setRemediationCoefficient("5d") .setDefaultRemediationCoefficient("1h") .setRemediationOffset("10h") diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java index 792fa6837da..9d969a68ce7 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java @@ -93,6 +93,10 @@ public abstract class Request { return Long.parseLong(s); } + public <E extends Enum<E>> E mandatoryParamAsEnum(String key, Class<E> enumClass) { + return Enum.valueOf(enumClass, mandatoryParam(key)); + } + public List<String> mandatoryParamAsStrings(String key) { List<String> values = paramAsStrings(key); if (values == null) { @@ -131,6 +135,22 @@ public abstract class Request { } @CheckForNull + public <E extends Enum<E>> List<E> paramAsEnums(String key, Class<E> enumClass) { + WebService.Param definition = action.param(key); + String value = readParamOrDefaultValue(key, definition); + if (value == null) { + return null; + } + Iterable<String> values = Splitter.on(',').omitEmptyStrings().trimResults().split(value); + List<E> result = Lists.newArrayList(); + for (String s : values) { + validate(s, definition); + result.add(Enum.valueOf(enumClass, s)); + } + return result; + } + + @CheckForNull private String readParamOrDefaultValue(String key, @Nullable WebService.Param definition) { if (definition == null) { String message = String.format("BUG - parameter '%s' is undefined for action '%s'", key, action.key()); @@ -212,4 +232,10 @@ public abstract class Request { String s = param(key); return s == null ? null : Long.parseLong(s); } + + @CheckForNull + public <E extends Enum<E>> E paramAsEnum(String key, Class<E> enumClass) { + String s = param(key); + return s == null ? null : Enum.valueOf(enumClass, s); + } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java index 5e464a4200f..9508fd1d179 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java @@ -32,10 +32,12 @@ import org.sonar.api.ServerExtension; 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.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} @@ -465,33 +467,27 @@ public interface WebService extends ServerExtension { /** * Exhaustive list of possible values when it makes sense, for example * list of severities. + * <p/> + * Note that the parameter supports values with type Iterable, for example : + * <pre> + * setPossibleValues(Arrays.asList("one", "two"), "three", "four"); + * </pre> * * @since 4.4 */ public NewParam setPossibleValues(@Nullable Object... values) { - return setPossibleValues(values == null ? (Collection) null : Arrays.asList(values)); - } - - /** - * @since 4.4 - */ - public NewParam setBooleanPossibleValues() { - return setPossibleValues("true", "false"); - } - - /** - * Exhaustive list of possible values when it makes sense, for example - * list of severities. - * - * @since 4.4 - */ - public NewParam setPossibleValues(@Nullable Collection values) { if (values == null) { this.possibleValues = null; } else { this.possibleValues = Sets.newLinkedHashSet(); for (Object value : values) { - this.possibleValues.add(value.toString()); + if (value instanceof Iterable) { + for (Object o : (Iterable) value) { + this.possibleValues.add(o.toString()); + } + } else { + this.possibleValues.add(value.toString()); + } } } return this; @@ -500,11 +496,43 @@ public interface WebService extends ServerExtension { /** * @since 4.4 */ + public NewParam setBooleanPossibleValues() { + return setPossibleValues("true", "false"); + } + + /** + * @since 4.4 + */ public NewParam setDefaultValue(@Nullable String s) { this.defaultValue = s; return this; } + @CheckForNull + public String description() { + return description; + } + + @CheckForNull + public String exampleValue() { + return exampleValue; + } + + @CheckForNull + public String defaultValue() { + return defaultValue; + } + + @CheckForNull + public boolean isRequired() { + return required; + } + + @CheckForNull + public Set<String> possibleValues() { + return possibleValues; + } + @Override public String toString() { return key; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java index 6387ecc42f0..5450a63e22a 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java @@ -327,17 +327,6 @@ public class JsonWriter { /** * @throws org.sonar.api.utils.text.WriterException on any failure */ - public JsonWriter prop(String name, @Nullable Object value) { - if(value != null) { - return name(name).value(value.toString()); - } else { - return this; - } - } - - /** - * @throws org.sonar.api.utils.text.WriterException on any failure - */ public JsonWriter prop(String name, boolean value) { return name(name).value(value); } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/server/ws/RequestTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/server/ws/RequestTest.java index ac46d611fc9..76421b05c18 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/server/ws/RequestTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/server/ws/RequestTest.java @@ -22,6 +22,7 @@ package org.sonar.api.server.ws; import com.google.common.collect.Maps; import org.junit.Before; import org.junit.Test; +import org.sonar.api.rule.RuleStatus; import javax.annotation.Nullable; import java.util.Map; @@ -68,10 +69,12 @@ public class RequestTest { action.createParam("a_string"); action.createParam("a_boolean"); action.createParam("a_number"); + action.createParam("a_enum"); action.createParam("a_required_string").setRequired(true); action.createParam("a_required_boolean").setRequired(true); action.createParam("a_required_number").setRequired(true); + action.createParam("a_required_enum").setRequired(true); action.createParam("has_default_string").setDefaultValue("the_default_string"); action.createParam("has_default_number").setDefaultValue("10"); @@ -107,11 +110,13 @@ public class RequestTest { request.setParam("a_required_string", "foo"); request.setParam("a_required_number", "42"); request.setParam("a_required_boolean", "true"); + request.setParam("a_required_enum", "BETA"); assertThat(request.mandatoryParam("a_required_string")).isEqualTo("foo"); assertThat(request.mandatoryParamAsBoolean("a_required_boolean")).isTrue(); assertThat(request.mandatoryParamAsInt("a_required_number")).isEqualTo(42); assertThat(request.mandatoryParamAsLong("a_required_number")).isEqualTo(42L); + assertThat(request.mandatoryParamAsEnum("a_required_enum", RuleStatus.class)).isEqualTo(RuleStatus.BETA); } @Test @@ -161,6 +166,17 @@ public class RequestTest { } @Test + public void param_as_enum() throws Exception { + assertThat(request.setParam("a_enum", "BETA").paramAsEnum("a_enum", RuleStatus.class)).isEqualTo(RuleStatus.BETA); + } + + @Test + public void param_as_enums() throws Exception { + assertThat(request.setParam("a_enum", "BETA,READY").paramAsEnums("a_enum", RuleStatus.class)).containsOnly( + RuleStatus.BETA, RuleStatus.READY); + } + + @Test public void param_as_strings() throws Exception { assertThat(request.paramAsStrings("a_string")).isNull(); assertThat(request.setParam("a_string", "").paramAsStrings("a_string")).isEmpty(); diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index 9cc6cb7ceb2..d6c1df951e2 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -202,7 +202,7 @@ class ServerComponents { ComponentDao.class, DbClient.class, MeasureFilterDao.class - )); + )); components.addAll(CorePropertyDefinitions.all()); components.addAll(DatabaseMigrations.CLASSES); components.addAll(DaoUtils.getDaoClasses()); @@ -327,8 +327,6 @@ class ServerComponents { pico.addSingleton(DeprecatedRulesDefinition.class); pico.addSingleton(RuleDefinitionsLoader.class); pico.addSingleton(RulesDefinitionXmlLoader.class); - - // experimental rules pico.addSingleton(RuleService.class); pico.addSingleton(RulesWebService.class); pico.addSingleton(SearchAction.class); @@ -336,6 +334,7 @@ class ServerComponents { pico.addSingleton(TagsAction.class); pico.addSingleton(SetTagsAction.class); pico.addSingleton(SetNoteAction.class); + pico.addSingleton(RuleMapping.class); pico.addSingleton(org.sonar.server.rule2.ws.AppAction.class); // measure diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleDoc.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleDoc.java index 2e7962b684a..e6555b786eb 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleDoc.java +++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleDoc.java @@ -35,7 +35,7 @@ public class ActiveRuleDoc extends BaseDoc implements ActiveRule { public ActiveRuleDoc(Map<String, Object> fields) { super(fields); - this.key = ActiveRuleKey.parse((String) get(ActiveRuleNormalizer.ActiveRuleField.KEY.key())); + this.key = ActiveRuleKey.parse((String) getField(ActiveRuleNormalizer.ActiveRuleField.KEY.key())); Preconditions.checkArgument(key!=null, "Invalid ActiveRuleKey!"); } @@ -46,12 +46,12 @@ public class ActiveRuleDoc extends BaseDoc implements ActiveRule { @Override public String severity() { - return (String) get(ActiveRuleNormalizer.ActiveRuleField.SEVERITY.key()); + return (String) getField(ActiveRuleNormalizer.ActiveRuleField.SEVERITY.key()); } @Override public ActiveRule.Inheritance inheritance() { - String inheritance = get(ActiveRuleNormalizer.ActiveRuleField.INHERITANCE.key()); + String inheritance = getField(ActiveRuleNormalizer.ActiveRuleField.INHERITANCE.key()); if (inheritance == null || inheritance.isEmpty() || inheritance.toLowerCase().contains("none")) { return Inheritance.NONE; @@ -67,7 +67,7 @@ public class ActiveRuleDoc extends BaseDoc implements ActiveRule { @Override @CheckForNull public ActiveRuleKey parentKey() { - String data = get(ActiveRuleNormalizer.ActiveRuleField.PARENT_KEY.key()); + String data = getField(ActiveRuleNormalizer.ActiveRuleField.PARENT_KEY.key()); if (data != null && !data.isEmpty()) { return ActiveRuleKey.parse(data); } @@ -77,7 +77,7 @@ public class ActiveRuleDoc extends BaseDoc implements ActiveRule { @Override public Map<String, String> params() { Map<String, String> params = new HashMap<String, String>(); - List<Map<String, String>> allParams = get(ActiveRuleNormalizer.ActiveRuleField.PARAMS.key()); + List<Map<String, String>> allParams = getField(ActiveRuleNormalizer.ActiveRuleField.PARAMS.key()); if (allParams != null) { for (Map<String, String> param : allParams) { params.put(param.get(ActiveRuleNormalizer.ActiveRuleParamField.NAME.key()), diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleIndex.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleIndex.java index 91fd57ee49d..8bc98b902b2 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleIndex.java +++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleIndex.java @@ -38,7 +38,6 @@ */ package org.sonar.server.qualityprofile.index; -import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.xcontent.XContentBuilder; diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BulkRuleActivationActions.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BulkRuleActivationActions.java index 95abdbcd4dc..d012b129af3 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BulkRuleActivationActions.java +++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BulkRuleActivationActions.java @@ -55,7 +55,7 @@ public class BulkRuleActivationActions implements ServerComponent { } }); - SearchAction.defineSearchParameters(activate); + SearchAction.defineRuleSearchParameters(activate); defineProfileKeyParameters(activate); activate.createParam("activation_severity") diff --git a/sonar-server/src/main/java/org/sonar/server/rule2/Rule.java b/sonar-server/src/main/java/org/sonar/server/rule2/Rule.java index 0da3048e839..2582e03c57b 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule2/Rule.java +++ b/sonar-server/src/main/java/org/sonar/server/rule2/Rule.java @@ -75,7 +75,6 @@ public interface Rule { @CheckForNull DebtRemediationFunction debtRemediationFunction(); - Date createdAt(); Date updatedAt(); 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 3a939593d3c..fbedb8a3f89 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 @@ -67,20 +67,16 @@ public class RuleService implements ServerComponent { } public RuleResult search(RuleQuery query, QueryOptions options) { - - /** keep only supported fields and add the fields to always return */ - options.filterFieldsToReturn(RuleIndex.PUBLIC_FIELDS); - 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){ + if(query.getQProfileKey() == null){ throw new IllegalStateException("\"activation=true\" requires a profile key!"); } - QualityProfileKey qualityProfileKey = QualityProfileKey.parse(query.getqProfileKey()); + QualityProfileKey qualityProfileKey = QualityProfileKey.parse(query.getQProfileKey()); result.getActiveRules().put(rule.key().toString(), activeRuleIndex.getByRuleKeyAndProfileKey(rule.key(),qualityProfileKey)); } @@ -98,7 +94,7 @@ public class RuleService implements ServerComponent { } /** - * List all tags + * List all tags, including system tags, defined on rules */ public Set<String> listTags() { return index.terms(RuleNormalizer.RuleField.TAGS.key(), RuleNormalizer.RuleField.SYSTEM_TAGS.key()); diff --git a/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleDoc.java b/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleDoc.java index 619e134e50b..2eee2f43884 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleDoc.java +++ b/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleDoc.java @@ -39,15 +39,15 @@ import java.util.Map; /** * Implementation of Rule based on an Elasticsearch document */ -class RuleDoc extends BaseDoc implements Rule { +public class RuleDoc extends BaseDoc implements Rule { - public RuleDoc(Map<String, Object> fields) { + RuleDoc(Map<String, Object> fields) { super(fields); } @Override public RuleKey key() { - String key = get(RuleField.KEY.key()); + String key = getField(RuleField.KEY.key()); if (key == null || key.isEmpty()) { throw new IllegalStateException("Missing values for RuleKey in RuleDoc"); } else { @@ -58,68 +58,68 @@ class RuleDoc extends BaseDoc implements Rule { @Override @CheckForNull public String internalKey() { - return get(RuleField.INTERNAL_KEY.key()); + return getField(RuleField.INTERNAL_KEY.key()); } @Override public String markdownNote() { - return get(RuleField.NOTE.key()); + return getField(RuleField.NOTE.key()); } @Override @CheckForNull public String language() { - return get(RuleField.LANGUAGE.key()); + return getField(RuleField.LANGUAGE.key()); } @Override @CheckForNull public String name() { - return get(RuleField.NAME.key()); + return getField(RuleField.NAME.key()); } @Override @CheckForNull public String htmlDescription() { - return get(RuleField.HTML_DESCRIPTION.key()); + return getField(RuleField.HTML_DESCRIPTION.key()); } @Override @CheckForNull public String severity() { - return (String) get(RuleField.SEVERITY.key()); + return (String) getField(RuleField.SEVERITY.key()); } @Override @CheckForNull public RuleStatus status() { - return RuleStatus.valueOf((String) get(RuleField.STATUS.key())); + return RuleStatus.valueOf((String) getField(RuleField.STATUS.key())); } @Override @CheckForNull public boolean template() { - return (Boolean) get(RuleField.TEMPLATE.key()); + return (Boolean) getField(RuleField.TEMPLATE.key()); } @Override @CheckForNull public List<String> tags() { - return (List<String>) get(RuleField.TAGS.key()); + return (List<String>) getField(RuleField.TAGS.key()); } @Override @CheckForNull public List<String> systemTags() { - return (List<String>) get(RuleField.SYSTEM_TAGS.key()); + return (List<String>) getField(RuleField.SYSTEM_TAGS.key()); } @Override @CheckForNull public List<RuleParam> params() { List<RuleParam> params = new ArrayList<RuleParam>(); - if (this.get(RuleField.PARAMS.key()) != null) { - List<Map<String, Object>> esParams = this.get(RuleField.PARAMS.key()); + if (this.getField(RuleField.PARAMS.key()) != null) { + List<Map<String, Object>> esParams = this.getField(RuleField.PARAMS.key()); for (final Map<String, Object> param : esParams) { params.add(new RuleParam() { { @@ -164,13 +164,13 @@ class RuleDoc extends BaseDoc implements Rule { @Override @CheckForNull public String debtSubCharacteristicKey(){ - return (String) get(RuleField.SUB_CHARACTERISTIC.key()); + return (String) getField(RuleField.SUB_CHARACTERISTIC.key()); } @Override @CheckForNull public DebtRemediationFunction debtRemediationFunction() { - final String function = this.get(RuleField.DEBT_FUNCTION_TYPE.key()); + final String function = this.getField(RuleField.DEBT_FUNCTION_TYPE.key()); if(function == null || function.isEmpty()){ return null; } else { @@ -182,12 +182,12 @@ class RuleDoc extends BaseDoc implements Rule { @Override public String coefficient() { - return (String) get(RuleField.DEBT_FUNCTION_COEFFICIENT.key()); + return (String) getField(RuleField.DEBT_FUNCTION_COEFFICIENT.key()); } @Override public String offset() { - return (String) get(RuleField.DEBT_FUNCTION_OFFSET.key()); + return (String) getField(RuleField.DEBT_FUNCTION_OFFSET.key()); } }; } @@ -196,29 +196,29 @@ class RuleDoc extends BaseDoc implements Rule { @Override @CheckForNull public String noteLogin() { - return (String) get(RuleField.NOTE_LOGIN.key()); + return (String) getField(RuleField.NOTE_LOGIN.key()); } @Override public Date noteCreatedAt() { - return IndexUtils.parseDateTime((String) get(RuleField.NOTE_CREATED_AT.key())); + return IndexUtils.parseDateTime((String) getField(RuleField.NOTE_CREATED_AT.key())); } @Override public Date noteUpdatedAt() { - return IndexUtils.parseDateTime((String) get(RuleField.NOTE_UPDATED_AT.key())); + return IndexUtils.parseDateTime((String) getField(RuleField.NOTE_UPDATED_AT.key())); } @Override @CheckForNull public Date createdAt() { - return IndexUtils.parseDateTime((String)get(RuleField.CREATED_AT.key())); + return IndexUtils.parseDateTime((String)getField(RuleField.CREATED_AT.key())); } @Override @CheckForNull public Date updatedAt() { - return IndexUtils.parseDateTime((String) get(RuleField.UPDATED_AT.key())); + return IndexUtils.parseDateTime((String) getField(RuleField.UPDATED_AT.key())); } @Override diff --git a/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleIndex.java b/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleIndex.java index 158f0ec6be4..2888e504f13 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleIndex.java +++ b/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleIndex.java @@ -252,10 +252,8 @@ public class RuleIndex extends BaseIndex<Rule, RuleDto, RuleKey> { Set<String> fields = new HashSet<String>(); if (options.getFieldsToReturn() != null && !options.getFieldsToReturn().isEmpty()) { fields.addAll(options.getFieldsToReturn()); - // required fields - // TODO remove REPOSITORY ? Move this list to RuleField constant ? + // required field fields.add(RuleNormalizer.RuleField.KEY.key()); - fields.add(RuleNormalizer.RuleField.REPOSITORY.key()); } else { fields = RuleNormalizer.RuleField.ALL_KEYS; } diff --git a/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleNormalizer.java b/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleNormalizer.java index 0a0d8951a9b..ba20242c89d 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleNormalizer.java +++ b/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleNormalizer.java @@ -55,10 +55,13 @@ public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> { TEMPLATE("template"), UPDATED_AT("updatedAt"), PARAMS("params"), + //TODO to be renamed debtRemFnXxx DEBT_FUNCTION_TYPE("debtFunction"), DEBT_FUNCTION_COEFFICIENT("debtCoefficient"), DEBT_FUNCTION_OFFSET("debtOffset"), + // TODO to be renamed debtSubChar SUB_CHARACTERISTIC("subCharacteristicKey"), + // TODO to be renamed markdownNote NOTE("note"), NOTE_LOGIN("noteLogin"), NOTE_CREATED_AT("noteCreatedAt"), @@ -188,8 +191,6 @@ public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> { } public UpdateRequest normalize(RuleParamDto param, RuleKey key) { - - Map<String, Object> newParam = new HashMap<String, Object>(); newParam.put("_id", param.getName()); newParam.put(RuleParamField.NAME.key(), param.getName()); diff --git a/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleQuery.java b/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleQuery.java index 5f8e189ee64..722bf243072 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleQuery.java +++ b/sonar-server/src/main/java/org/sonar/server/rule2/index/RuleQuery.java @@ -29,8 +29,6 @@ import java.util.Collection; public class RuleQuery { - - public static enum SortField { KEY(RuleNormalizer.RuleField.KEY), REPOSITORY(RuleNormalizer.RuleField.REPOSITORY), @@ -81,17 +79,18 @@ public class RuleQuery { /** + * TODO should not be public * @see org.sonar.server.rule2.RuleService#newRuleQuery() */ public RuleQuery() { } @CheckForNull - public String getqProfileKey() { + public String getQProfileKey() { return qProfileKey; } - public RuleQuery setqProfileKey(String qProfileKey) { + public RuleQuery setQProfileKey(String qProfileKey) { this.qProfileKey = qProfileKey; return this; } diff --git a/sonar-server/src/main/java/org/sonar/server/rule2/ws/RuleMapping.java b/sonar-server/src/main/java/org/sonar/server/rule2/ws/RuleMapping.java new file mode 100644 index 00000000000..2e131fa2eca --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/rule2/ws/RuleMapping.java @@ -0,0 +1,112 @@ +/* + * 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.resources.Language; +import org.sonar.api.resources.Languages; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.markdown.Markdown; +import org.sonar.server.rule2.Rule; +import org.sonar.server.rule2.RuleParam; +import org.sonar.server.rule2.index.RuleNormalizer; +import org.sonar.server.search.ws.BaseMapping; +import org.sonar.server.text.MacroInterpreter; + +public class RuleMapping extends BaseMapping { + + private final Languages languages; + private final MacroInterpreter macroInterpreter; + + public RuleMapping(Languages languages, MacroInterpreter macroInterpreter) { + this.languages = languages; + this.macroInterpreter = macroInterpreter; + } + + @Override + protected void doInit() { + addIndexField("repo", RuleNormalizer.RuleField.REPOSITORY.key()); + addIndexField("name", RuleNormalizer.RuleField.NAME.key()); + addIndexField("htmlDesc", RuleNormalizer.RuleField.HTML_DESCRIPTION.key()); + addIndexField("severity", RuleNormalizer.RuleField.SEVERITY.key()); + addIndexField("status", RuleNormalizer.RuleField.STATUS.key()); + addIndexField("internalKey", RuleNormalizer.RuleField.INTERNAL_KEY.key()); + addIndexBooleanField("template", RuleNormalizer.RuleField.TEMPLATE.key()); + addIndexArrayField("tags", RuleNormalizer.RuleField.TAGS.key()); + addIndexArrayField("sysTags", RuleNormalizer.RuleField.SYSTEM_TAGS.key()); + addIndexField("debtSubChar", RuleNormalizer.RuleField.SUB_CHARACTERISTIC.key()); + addField("debtRemFn", new IndexField("debtRemFnType", RuleNormalizer.RuleField.DEBT_FUNCTION_TYPE.key())); + addField("debtRemFn", new IndexField("debtRemFnCoeff", RuleNormalizer.RuleField.DEBT_FUNCTION_COEFFICIENT.key())); + addField("debtRemFn", new IndexField("debtRemFnOffset", RuleNormalizer.RuleField.DEBT_FUNCTION_OFFSET.key())); + addIndexField("mdNote", RuleNormalizer.RuleField.NOTE.key()); + // TODO how to require NOTE ? + addField("htmlNote", new HtmlNoteField(macroInterpreter)); + addIndexField("noteLogin", RuleNormalizer.RuleField.NOTE_LOGIN.key()); + addIndexField("lang", RuleNormalizer.RuleField.LANGUAGE.key()); + addField("langName", new LangNameField(languages)); + addField("params", new ParamsField()); + } + + private static class ParamsField implements Field<Rule> { + @Override + public void write(JsonWriter json, Rule rule) { + json.name("params").beginArray(); + for (RuleParam param : rule.params()) { + json + .beginObject() + .prop("key", param.key()) + .prop("desc", param.description()) + .prop("defaultValue", param.defaultValue()) + .endObject(); + } + json.endArray(); + } + } + + private static class LangNameField implements Field<Rule> { + private final Languages languages; + + private LangNameField(Languages languages) { + this.languages = languages; + } + + @Override + public void write(JsonWriter json, Rule rule) { + String langKey = rule.language(); + Language lang = languages.get(langKey); + json.prop("langName", lang != null ? lang.getName() : null); + } + } + + private static class HtmlNoteField implements Field<Rule> { + private final MacroInterpreter macroInterpreter; + + private HtmlNoteField(MacroInterpreter macroInterpreter) { + this.macroInterpreter = macroInterpreter; + } + + @Override + public void write(JsonWriter json, Rule rule) { + String markdownNote = rule.markdownNote(); + if (markdownNote != null) { + json.prop("htmlNote", macroInterpreter.interpret(Markdown.convertToHtml(markdownNote))); + } + } + } +} 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 d1223ca35ce..bde40f79dbb 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 @@ -19,10 +19,7 @@ */ package org.sonar.server.rule2.ws; -import com.google.common.base.Function; -import com.google.common.collect.Collections2; import com.google.common.io.Resources; -import com.google.gson.Gson; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.api.server.ws.Request; @@ -32,18 +29,14 @@ 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.RuleParam; import org.sonar.server.rule2.RuleService; -import org.sonar.server.rule2.index.RuleIndex; +import org.sonar.server.rule2.index.RuleDoc; 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.search.QueryOptions; +import org.sonar.server.search.ws.SearchOptions; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; import java.util.Collection; -import java.util.List; import java.util.Map; /** @@ -51,7 +44,6 @@ import java.util.Map; */ public class SearchAction implements RequestHandler { - private static final String PARAM_TEXT_QUERY = "q"; private static final String PARAM_REPOSITORIES = "repositories"; private static final String PARAM_ACTIVATION = "activation"; private static final String PARAM_QPROFILE = "qprofile"; @@ -63,17 +55,12 @@ public class SearchAction implements RequestHandler { private static final String PARAM_TAGS = "tags"; private static final String PARAM_ALL_OF_TAGS = "all_of_tags"; - // generic search parameters - private static final String PARAM_PAGE = "p"; - private static final String PARAM_PAGE_SIZE = "ps"; - private static final String PARAM_FIELDS = "f"; - private static final String PARAM_SORT = "s"; - private static final String PARAM_ASCENDING = "asc"; - private final RuleService service; + private final RuleMapping mapping; - public SearchAction(RuleService service) { + public SearchAction(RuleService service, RuleMapping mapping) { this.service = service; + this.mapping = mapping; } void define(WebService.NewController controller) { @@ -84,42 +71,16 @@ public class SearchAction implements RequestHandler { .setSince("4.4") .setHandler(this); - defineSearchParameters(action); - - action - .createParam(PARAM_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(String.format("%s,%s,%s", RuleNormalizer.RuleField.KEY, RuleNormalizer.RuleField.REPOSITORY, RuleNormalizer.RuleField.LANGUAGE)); - - action - .createParam(PARAM_PAGE) - .setDescription("1-based page number") - .setExampleValue("42") - .setDefaultValue("1"); - - action - .createParam(PARAM_PAGE_SIZE) - .setDescription("Page size. Must be greater than 0.") - .setExampleValue("10") - .setDefaultValue("25"); - - // TODO limit the fields to sort on + document possible values + default value ? - action - .createParam(PARAM_SORT) - .setDescription("Sort field") - .setExampleValue(RuleNormalizer.RuleField.LANGUAGE.key()); - - action - .createParam(PARAM_ASCENDING) - .setDescription("Ascending sort") - .setBooleanPossibleValues() - .setDefaultValue("true"); + SearchOptions.defineGenericParameters(action, mapping.supportedFields(), "actives"); + defineRuleSearchParameters(action); } - public static void defineSearchParameters(WebService.NewAction action) { + /** + * public visibility because used by {@link org.sonar.server.qualityprofile.ws.BulkRuleActivationActions} + */ + public static void defineRuleSearchParameters(WebService.NewAction action) { action - .createParam(PARAM_TEXT_QUERY) + .createParam(SearchOptions.PARAM_TEXT_QUERY) .setDescription("UTF-8 search query") .setExampleValue("null pointer"); @@ -175,132 +136,88 @@ public class SearchAction implements RequestHandler { .setDescription("Used only if 'qprofile' is set") .setExampleValue("java:Sonar way") .setPossibleValues("false", "true", "all"); + + // TODO limit the fields to sort on + document possible values + default value ? + action + .createParam(SearchOptions.PARAM_SORT) + .setDescription("Sort field") + .setExampleValue(RuleNormalizer.RuleField.LANGUAGE.key()); + + action + .createParam(SearchOptions.PARAM_ASCENDING) + .setDescription("Ascending sort") + .setBooleanPossibleValues() + .setDefaultValue("true"); } @Override public void handle(Request request, Response response) { - RuleQuery query = service.newRuleQuery(); - query.setQueryText(request.param(PARAM_TEXT_QUERY)); - query.setSeverities(request.paramAsStrings(PARAM_SEVERITIES)); - query.setRepositories(request.paramAsStrings(PARAM_REPOSITORIES)); - query.setStatuses(toStatuses(request.paramAsStrings(PARAM_STATUSES))); - 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.setqProfileKey(request.param(PARAM_QPROFILE)); + RuleQuery query = createRuleQuery(request); + SearchOptions searchOptions = SearchOptions.create(request); - // TODO move to QueryOptions ? - query.setSortField(RuleQuery.SortField.valueOfOrNull(request.param(PARAM_SORT))); - query.setAscendingSort(request.mandatoryParamAsBoolean(PARAM_ASCENDING)); - - QueryOptions options = new QueryOptions(); - options.setFieldsToReturn(request.paramAsStrings(PARAM_FIELDS)); - options.setPage( - request.mandatoryParamAsInt(PARAM_PAGE), - request.mandatoryParamAsInt(PARAM_PAGE_SIZE)); - - RuleResult results = service.search(query, options); + RuleResult results = service.search(query, mapping.newQueryOptions(searchOptions)); JsonWriter json = response.newJsonWriter().beginObject(); - writeStatistics(results, json); - writeRequestParams(request, json); - writeRules(results, json); + searchOptions.writeStatistics(json, results); + writeRules(results, json, searchOptions); + if (searchOptions.hasField("actives")) { + writeActiveRules(results, json); + } json.endObject(); json.close(); } - private void writeStatistics(RuleResult results, JsonWriter json) { - json.prop("total", results.getTotal()); - } - - private void writeRequestParams(Request request,JsonWriter json ){ - json.prop(PARAM_PAGE, request.mandatoryParamAsInt(PARAM_PAGE)); - json.prop(PARAM_PAGE_SIZE, request.mandatoryParamAsInt(PARAM_PAGE_SIZE)); + private RuleQuery createRuleQuery(Request request) { + RuleQuery query = service.newRuleQuery(); + query.setQueryText(request.param(SearchOptions.PARAM_TEXT_QUERY)); + query.setSeverities(request.paramAsStrings(PARAM_SEVERITIES)); + query.setRepositories(request.paramAsStrings(PARAM_REPOSITORIES)); + query.setStatuses(request.paramAsEnums(PARAM_STATUSES, RuleStatus.class)); + 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.setQProfileKey(request.param(PARAM_QPROFILE)); + query.setSortField(RuleQuery.SortField.valueOfOrNull(request.param(SearchOptions.PARAM_SORT))); + query.setAscendingSort(request.mandatoryParamAsBoolean(SearchOptions.PARAM_ASCENDING)); + return query; } - private void writeRules(RuleResult result, JsonWriter json) { + private void writeRules(RuleResult result, JsonWriter json, SearchOptions options) { json.name("rules").beginArray(); for (Rule rule : result.getHits()) { + mapping.write((RuleDoc) rule, json, options.fields()); + } + json.endArray(); + } - /** Rule */ - json.beginObject(); - json - .prop("repo", rule.key().repository()) - .prop("key", rule.key().toString()) - .prop("lang", rule.language()) - .prop("name", rule.name()) - .prop("htmlDesc", rule.htmlDescription()) - .prop("status", rule.status()) - .prop("template", rule.template()) - .prop("internalKey", rule.internalKey()) - .prop("severity", rule.severity()) - .prop("markdownNote", rule.markdownNote()) - .prop("noteLogin", rule.noteLogin()) - .name("tags").beginArray().values(rule.tags()).endArray() - .name("sysTags").beginArray().values(rule.systemTags()).endArray() - .prop("debtSubCharacteristicKey", rule.debtSubCharacteristicKey()); - - if(rule.debtRemediationFunction() != null){ - json - .prop("debtRemediationFunctionType", rule.debtRemediationFunction().type().name()) - .prop("debtRemediationFunctionCoefficient", rule.debtRemediationFunction().coefficient()) - .prop("debtRemediationFunctionOffset", rule.debtRemediationFunction().offset()); - } - - /** RuleParams */ - json.name("params").beginArray(); - for (RuleParam param : rule.params()) { - json - .beginObject() - .prop("key", param.key()) - .prop("desc", param.description()) - .prop("defaultValue", param.defaultValue()) - .endObject(); - } - json.endArray(); - - /** ActiveRules */ - json.name("actives").beginArray(); - for (ActiveRule activeRule : result.getActiveRules().get(rule.key().toString())) { + 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()) { json .beginObject() - .prop("key",activeRule.key()) - .prop("inherit", activeRule.inheritance()) + .prop("qProfile", activeRule.key().qProfile().toString()) + .prop("inherit", activeRule.inheritance().toString()) .prop("severity", activeRule.severity()); - // TODO -// if(activeRule.parentKey() != null){ -// json.prop("parent",activeRule.parentKey()); -// } - - json - .name("params").beginArray(); + 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() + json + .beginObject() .prop("key", param.getKey()) .prop("value", param.getValue()) .endObject(); } - json.endArray(); - json.endObject(); + json.endArray().endObject(); } json.endArray(); - json.endObject(); - } - json.endArray(); - } - - - @CheckForNull - private Collection<RuleStatus> toStatuses(@Nullable List<String> statuses) { - if (statuses == null) { - return null; } - return Collections2.transform(statuses, new Function<String, RuleStatus>() { - @Override - public RuleStatus apply(@Nullable String input) { - return input == null ? null : RuleStatus.valueOf(input); - } - }); + json.endObject(); } } diff --git a/sonar-server/src/main/java/org/sonar/server/search/BaseDoc.java b/sonar-server/src/main/java/org/sonar/server/search/BaseDoc.java index 383b2e6ce19..966e714ea44 100644 --- a/sonar-server/src/main/java/org/sonar/server/search/BaseDoc.java +++ b/sonar-server/src/main/java/org/sonar/server/search/BaseDoc.java @@ -33,8 +33,12 @@ public abstract class BaseDoc { this.fields = fields; } + public String keyField() { + return (String)fields.get("key"); + } + @CheckForNull - protected <K> K get(String key) { + public <K> K getField(String key) { if (!fields.containsKey(key)) { throw new IllegalStateException(String.format("Field %s not specified in query options", key)); } diff --git a/sonar-server/src/main/java/org/sonar/server/search/IndexUtils.java b/sonar-server/src/main/java/org/sonar/server/search/IndexUtils.java index a0f41d71660..febc8dcfcff 100644 --- a/sonar-server/src/main/java/org/sonar/server/search/IndexUtils.java +++ b/sonar-server/src/main/java/org/sonar/server/search/IndexUtils.java @@ -20,6 +20,7 @@ package org.sonar.server.search; import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -32,16 +33,15 @@ public class IndexUtils { } @CheckForNull - public static Date parseDateTime(String s) { + public static Date parseDateTime(@Nullable String s) { DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); if (s == null) { return null; - } else { - try { - return sdf.parse(s); - } catch (ParseException e) { - throw new IllegalArgumentException("Cannot parse ES date: " + s, e); - } + } + try { + return sdf.parse(s); + } catch (ParseException e) { + throw new IllegalArgumentException("Cannot parse ES date: " + s, e); } } } 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 1f2c6cd8b60..2a1c8e8c0a0 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,8 +20,6 @@ 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; @@ -32,6 +30,7 @@ import java.util.Set; /** * Options about paging, sorting and fields to return + * * @since 4.4 */ public class QueryOptions { @@ -47,11 +46,7 @@ public class QueryOptions { private boolean facet = DEFAULT_FACET; - private Set<String> fieldsToReturn; - - public QueryOptions() { - fieldsToReturn = new HashSet<String>(); - } + private Set<String> fieldsToReturn = new HashSet<String>(); /** * Whether or not the search returns facets for the domain. Defaults to {@link #DEFAULT_OFFSET} @@ -116,41 +111,26 @@ public class QueryOptions { } public QueryOptions setFieldsToReturn(@Nullable Collection<String> c) { - this.fieldsToReturn = (c == null ? null : Sets.newHashSet(c)); + this.fieldsToReturn.clear(); + if (c != null) { + this.fieldsToReturn.addAll(c); + } return this; } public QueryOptions addFieldsToReturn(@Nullable Collection<String> c) { if (c != null) { - if (fieldsToReturn == null) { - fieldsToReturn = Sets.newHashSet(c); - } else { - fieldsToReturn.addAll(c); - } + fieldsToReturn.addAll(c); } return this; } public QueryOptions addFieldsToReturn(String... c) { - if (fieldsToReturn == null) { - fieldsToReturn = Sets.newHashSet(c); - } else { - fieldsToReturn.addAll(Arrays.asList(c)); - } + fieldsToReturn.addAll(Arrays.asList(c)); return this; } - public QueryOptions filterFieldsToReturn(final Set<String> keep) { - if (fieldsToReturn == null) { - fieldsToReturn = Sets.newHashSet(keep); - } else { - fieldsToReturn = Sets.filter(fieldsToReturn, new Predicate<String>() { - @Override - public boolean apply(@Nullable String input) { - return input != null && keep.contains(input); - } - }); - } - return this; + public boolean hasFieldToReturn(String key) { + return fieldsToReturn.isEmpty() || fieldsToReturn.contains(key); } } diff --git a/sonar-server/src/main/java/org/sonar/server/search/Result.java b/sonar-server/src/main/java/org/sonar/server/search/Result.java index 2b208a7a0c3..23a407a5e4b 100644 --- a/sonar-server/src/main/java/org/sonar/server/search/Result.java +++ b/sonar-server/src/main/java/org/sonar/server/search/Result.java @@ -32,7 +32,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -public abstract class Result<K> { +public abstract class Result<K> { private final List<K> hits; private final Map<String, Collection<FacetValue>> facets; diff --git a/sonar-server/src/main/java/org/sonar/server/search/ws/BaseMapping.java b/sonar-server/src/main/java/org/sonar/server/search/ws/BaseMapping.java new file mode 100644 index 00000000000..6f15bc24bb1 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/search/ws/BaseMapping.java @@ -0,0 +1,188 @@ +/* + * 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.search.ws; + +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; +import org.picocontainer.Startable; +import org.sonar.api.ServerComponent; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.server.search.BaseDoc; +import org.sonar.server.search.IndexUtils; +import org.sonar.server.search.QueryOptions; + +import javax.annotation.Nullable; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +/** + * Mapping of search documents (see BaseDoc) to WS JSON responses + */ +public abstract class BaseMapping implements ServerComponent, Startable { + + private final Multimap<String, String> indexFields = LinkedHashMultimap.create(); + private final Multimap<String, BaseMapping.Field> fields = LinkedHashMultimap.create(); + + @Override + public final void start() { + doInit(); + } + + protected abstract void doInit(); + + @Override + public final void stop() { + // do nothing + } + + public Set<String> supportedFields() { + return fields.keySet(); + } + + public QueryOptions newQueryOptions(SearchOptions options) { + QueryOptions result = new QueryOptions(); + result.setPage(options.page(), options.pageSize()); + List<String> optionFields = options.fields(); + if (optionFields != null) { + for (String optionField : optionFields) { + result.addFieldsToReturn(this.indexFields.get(optionField)); + } + } + return result; + } + + public void write(BaseDoc doc, JsonWriter json, @Nullable Collection<String> fieldsToReturn) { + json.beginObject(); + json.prop("key", doc.keyField()); + if (fieldsToReturn == null || fieldsToReturn.isEmpty()) { + // return all fields + for (BaseMapping.Field field : fields.values()) { + field.write(json, doc); + } + } else { + for (String optionField : fieldsToReturn) { + for (BaseMapping.Field field : fields.get(optionField)) { + field.write(json, doc); + } + } + } + json.endObject(); + } + + protected BaseMapping addIndexField(String key, String indexKey) { + indexFields.put(key, indexKey); + fields.put(key, new BaseMapping.IndexField(key, indexKey)); + return this; + } + + protected BaseMapping addIndexBooleanField(String key, String indexKey) { + indexFields.put(key, indexKey); + fields.put(key, new BaseMapping.IndexBooleanField(key, indexKey)); + return this; + } + + protected BaseMapping addIndexDatetimeField(String key, String indexKey) { + indexFields.put(key, indexKey); + fields.put(key, new BaseMapping.IndexDatetimeField(key, indexKey)); + return this; + } + + protected BaseMapping addIndexArrayField(String key, String indexKey) { + indexFields.put(key, indexKey); + fields.put(key, new BaseMapping.IndexArrayField(key, indexKey)); + return this; + } + + protected BaseMapping addField(String key, BaseMapping.Field field) { + fields.put(key, field); + return this; + } + + public static interface Field<D> { + void write(JsonWriter json, D doc); + } + + /** + * String field + */ + public static class IndexField implements Field<BaseDoc> { + private final String key, indexKey; + + public IndexField(String key, String indexKey) { + this.key = key; + this.indexKey = indexKey; + } + + @Override + public void write(JsonWriter json, BaseDoc doc) { + Object val = doc.getField(indexKey); + json.prop(key, val != null ? val.toString() : null); + } + } + + public static class IndexBooleanField implements Field<BaseDoc> { + private final String key, indexKey; + + public IndexBooleanField(String key, String indexKey) { + this.key = key; + this.indexKey = indexKey; + } + + @Override + public void write(JsonWriter json, BaseDoc doc) { + Boolean val = doc.getField(indexKey); + json.prop(key, val != null ? val.booleanValue() : null); + } + } + + public static class IndexArrayField implements Field<BaseDoc> { + private final String key, indexKey; + + public IndexArrayField(String key, String indexKey) { + this.key = key; + this.indexKey = indexKey; + } + + @Override + public void write(JsonWriter json, BaseDoc doc) { + Iterable<String> values = doc.getField(indexKey); + json.name(key).beginArray().values(values).endArray(); + } + } + + public static class IndexDatetimeField implements Field<BaseDoc> { + private final String key, indexKey; + + public IndexDatetimeField(String key, String indexKey) { + this.key = key; + this.indexKey = indexKey; + } + + @Override + public void write(JsonWriter json, BaseDoc doc) { + String val = doc.getField(indexKey); + if (val != null) { + json.propDateTime(key, IndexUtils.parseDateTime(val)); + } + } + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/search/ws/SearchOptions.java b/sonar-server/src/main/java/org/sonar/server/search/ws/SearchOptions.java new file mode 100644 index 00000000000..870b31f7d79 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/search/ws/SearchOptions.java @@ -0,0 +1,117 @@ +/* + * 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.search.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.server.search.Result; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import java.util.Iterator; +import java.util.List; + +/** + * Generic options for search web services + */ +public class SearchOptions { + + public static final String PARAM_TEXT_QUERY = "q"; + public static final String PARAM_PAGE = "p"; + public static final String PARAM_PAGE_SIZE = "ps"; + public static final String PARAM_FIELDS = "f"; + public static final String PARAM_SORT = "s"; + public static final String PARAM_ASCENDING = "asc"; + + private int pageSize; + private int page; + private List<String> fields; + + public int pageSize() { + return pageSize; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } + + /** + * 1-based page id + */ + public int page() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + @CheckForNull + public List<String> fields() { + return fields; + } + + public void setFields(@Nullable List<String> fields) { + this.fields = fields; + } + + public boolean hasField(String key) { + return fields == null || fields.contains(key); + } + + public SearchOptions writeStatistics(JsonWriter json, Result searchResult) { + json.prop("total", searchResult.getTotal()); + json.prop(PARAM_PAGE, page); + json.prop(PARAM_PAGE_SIZE, pageSize); + return this; + } + + public static SearchOptions create(Request request) { + SearchOptions options = new SearchOptions(); + options.setPage(request.mandatoryParamAsInt(PARAM_PAGE)); + options.setPageSize(request.mandatoryParamAsInt(PARAM_PAGE_SIZE)); + options.setFields(request.paramAsStrings(PARAM_FIELDS)); + return options; + } + + public static void defineGenericParameters(WebService.NewAction action, Object... possibleValues) { + WebService.NewParam newParam = action + .createParam(PARAM_FIELDS) + .setDescription("Comma-separated list of the fields to be returned in response. All the fields are returned by default.") + .setPossibleValues(possibleValues); + if (newParam.possibleValues() != null && newParam.possibleValues().size() > 1) { + Iterator<String> it = newParam.possibleValues().iterator(); + newParam.setExampleValue(String.format("%s,%s", it.next(), it.next())); + } + + action + .createParam(PARAM_PAGE) + .setDescription("1-based page number") + .setExampleValue("42") + .setDefaultValue("1"); + + action + .createParam(PARAM_PAGE_SIZE) + .setDescription("Page size. Must be greater than 0.") + .setExampleValue("10") + .setDefaultValue("25"); + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/search/SourceFields.java b/sonar-server/src/main/java/org/sonar/server/search/ws/package-info.java index 2afdaec154c..b9b48c78900 100644 --- a/sonar-server/src/main/java/org/sonar/server/search/SourceFields.java +++ b/sonar-server/src/main/java/org/sonar/server/search/ws/package-info.java @@ -17,13 +17,7 @@ * 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.search; +@ParametersAreNonnullByDefault +package org.sonar.server.search.ws; -import java.util.Map; - -public class SourceFields { - - public static String get(String key, Map<String,Object> source, QueryOptions options) { - return null; - } -} +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/sonar-server/src/main/resources/org/sonar/server/rule2/ws/example-search.json b/sonar-server/src/main/resources/org/sonar/server/rule2/ws/example-search.json index a94500f1ec9..b8c2f661747 100644 --- a/sonar-server/src/main/resources/org/sonar/server/rule2/ws/example-search.json +++ b/sonar-server/src/main/resources/org/sonar/server/rule2/ws/example-search.json @@ -3,6 +3,7 @@ "key": "squid:S1067", "repo": "squid", "lang": "java", + "langName": "Java", "name": "Expressions should not be too complex", "htmlDesc": "<p>\nThe complexity of an expression is defined by the number of <code>&&</code>, <code>||</code> and <code>condition ? ifTrue : ifFalse</code> operators it contains.\nA single expression's complexity should not become too high to keep the code readable.\n</p>\n\n<p>The following code, with a maximum complexity of 3:</p>\n\n<pre>\nif (condition1 && condition2 && condition3 && condition4) { /* ... */ } // Non-Compliant\n</pre>\n\n<p>could be refactored into something like:</p>\n\n<pre>\nif (relevantMethodName1() && relevantMethodName2()) { /* ... */ } // Compliant\n\n/* ... */\n\nprivate boolean relevantMethodName1() {\n return condition1 && condition2;\n}\n\nprivate boolean relevantMethodName2() {\n return condition3 && condition4;\n}\n</pre>", "status": "READY", @@ -493,4 +494,4 @@ } ] } -]}
\ No newline at end of file +]} diff --git a/sonar-server/src/test/java/org/sonar/server/debt/DebtModelBackupTest.java b/sonar-server/src/test/java/org/sonar/server/debt/DebtModelBackupTest.java index 8cbbcb43bb6..8cf19f011bc 100644 --- a/sonar-server/src/test/java/org/sonar/server/debt/DebtModelBackupTest.java +++ b/sonar-server/src/test/java/org/sonar/server/debt/DebtModelBackupTest.java @@ -166,7 +166,11 @@ public class DebtModelBackupTest { when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( // Rule with overridden debt values - new RuleDto().setRepositoryKey("squid").setRuleKey("UselessImportCheck").setSubCharacteristicId(2).setRemediationFunction("LINEAR_OFFSET").setRemediationCoefficient("2h").setRemediationOffset("15min"), + new RuleDto().setRepositoryKey("squid").setRuleKey("UselessImportCheck") + .setSubCharacteristicId(2) + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) + .setRemediationCoefficient("2h") + .setRemediationOffset("15min"), // Rule with default debt values new RuleDto().setRepositoryKey("squid").setRuleKey("AvoidNPE").setDefaultSubCharacteristicId(2).setDefaultRemediationFunction("LINEAR").setDefaultRemediationCoefficient("2h") @@ -232,8 +236,12 @@ public class DebtModelBackupTest { // Rule with default debt values : default value is linear (only coefficient is set) and overridden value is constant per issue (only offset is set) // -> Ony offset should be set new RuleDto().setRepositoryKey("squid").setRuleKey("AvoidNPE") - .setDefaultSubCharacteristicId(2).setDefaultRemediationFunction("LINEAR").setDefaultRemediationCoefficient("2h") - .setSubCharacteristicId(2).setRemediationFunction("CONSTANT_ISSUE").setRemediationOffset("15min") + .setDefaultSubCharacteristicId(2) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationCoefficient("2h") + .setSubCharacteristicId(2) + .setRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE.toString()) + .setRemediationOffset("15min") )); debtModelBackup.backup(); @@ -264,11 +272,16 @@ public class DebtModelBackupTest { when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( new RuleDto().setId(1).setRepositoryKey("squid").setRuleKey("UselessImportCheck").setLanguage("java") - .setSubCharacteristicId(2).setRemediationFunction("CONSTANT_ISSUE").setRemediationOffset("15min"), + .setSubCharacteristicId(2) + .setRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE.toString()) + .setRemediationOffset("15min"), // .setCreatedAt(oldDate).setUpdatedAt(oldDate), // Should be ignored - new RuleDto().setId(2).setRepositoryKey("checkstyle").setLanguage("java2") - .setSubCharacteristicId(3).setRemediationFunction("LINEAR").setRemediationCoefficient("2h") + new RuleDto().setId(2).setRepositoryKey("checkstyle") + .setLanguage("java2") + .setSubCharacteristicId(3) + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setRemediationCoefficient("2h") // .setCreatedAt(oldDate).setUpdatedAt(oldDate) )); @@ -415,9 +428,13 @@ public class DebtModelBackupTest { when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( new RuleDto().setRepositoryKey("squid").setRuleKey("NPE") - .setDefaultSubCharacteristicId(10).setDefaultRemediationFunction("LINEAR").setDefaultRemediationCoefficient("2h") - .setSubCharacteristicId(2).setRemediationFunction("LINEAR_OFFSET").setRemediationCoefficient("2h").setRemediationOffset("15min") -// .setCreatedAt(oldDate).setUpdatedAt(oldDate) + .setDefaultSubCharacteristicId(10) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationCoefficient("2h") + .setSubCharacteristicId(2) + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) + .setRemediationCoefficient("2h") + .setRemediationOffset("15min") )); RulesDefinition.Context context = new RulesDefinition.Context(); @@ -473,9 +490,13 @@ public class DebtModelBackupTest { when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( new RuleDto().setRepositoryKey("squid").setRuleKey("NPE") - .setDefaultSubCharacteristicId(10).setDefaultRemediationFunction("LINEAR").setDefaultRemediationCoefficient("2h") - .setSubCharacteristicId(2).setRemediationFunction("LINEAR_OFFSET").setRemediationCoefficient("2h").setRemediationOffset("15min") - //.setCreatedAt(oldDate).setUpdatedAt(oldDate) + .setDefaultSubCharacteristicId(10) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationCoefficient("2h") + .setSubCharacteristicId(2) + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) + .setRemediationCoefficient("2h") + .setRemediationOffset("15min") )); RulesDefinition.Context context = new RulesDefinition.Context(); @@ -523,12 +544,16 @@ public class DebtModelBackupTest { when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( // Template rule new RuleDto().setId(5).setRepositoryKey("squid").setRuleKey("XPath") - .setSubCharacteristicId(2).setRemediationFunction("LINEAR_OFFSET").setRemediationCoefficient("2h").setRemediationOffset("15min"), - // .setCreatedAt(oldDate).setUpdatedAt(oldDate), + .setSubCharacteristicId(2) + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) + .setRemediationCoefficient("2h") + .setRemediationOffset("15min"), // Custom rule new RuleDto().setId(6).setRepositoryKey("squid").setRuleKey("XPath_1369910135").setParentId(5) - .setSubCharacteristicId(2).setRemediationFunction("LINEAR_OFFSET").setRemediationCoefficient("2h").setRemediationOffset("15min") -// .setCreatedAt(oldDate).setUpdatedAt(oldDate) + .setSubCharacteristicId(2) + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) + .setRemediationCoefficient("2h") + .setRemediationOffset("15min") )); RulesDefinition.Context context = new RulesDefinition.Context(); @@ -668,12 +693,14 @@ public class DebtModelBackupTest { when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( new RuleDto().setId(1).setRepositoryKey("squid").setRuleKey("UselessImportCheck").setLanguage("java") - .setDefaultSubCharacteristicId(10).setDefaultRemediationFunction("LINEAR").setDefaultRemediationCoefficient("2h"), -// .setCreatedAt(oldDate).setUpdatedAt(oldDate), + .setDefaultSubCharacteristicId(10) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationCoefficient("2h"), // Should be ignored new RuleDto().setId(2).setRepositoryKey("checkstyle").setLanguage("java2") - .setSubCharacteristicId(3).setRemediationFunction("LINEAR").setRemediationCoefficient("2h") -// .setCreatedAt(oldDate).setUpdatedAt(oldDate) + .setSubCharacteristicId(3) + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setRemediationCoefficient("2h") )); debtModelBackup.restoreFromXml("<xml/>", "java"); @@ -717,8 +744,10 @@ public class DebtModelBackupTest { // Rule does not exits in XML -> debt will be disabled new RuleDto().setId(1).setRepositoryKey("squid").setRuleKey("UselessImportCheck").setLanguage("java") .setDefaultSubCharacteristicId(2).setDefaultRemediationFunction("LINEAR").setDefaultRemediationCoefficient("2h") - .setSubCharacteristicId(2).setRemediationFunction("LINEAR_OFFSET").setRemediationCoefficient("2h").setRemediationOffset("15min") -// .setCreatedAt(oldDate).setUpdatedAt(oldDate) + .setSubCharacteristicId(2) + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) + .setRemediationCoefficient("2h") + .setRemediationOffset("15min") )); debtModelBackup.restoreFromXml("<xml/>", "java"); diff --git a/sonar-server/src/test/java/org/sonar/server/debt/DebtModelOperationsTest.java b/sonar-server/src/test/java/org/sonar/server/debt/DebtModelOperationsTest.java index df890a22bbb..451c73493a5 100644 --- a/sonar-server/src/test/java/org/sonar/server/debt/DebtModelOperationsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/debt/DebtModelOperationsTest.java @@ -31,6 +31,7 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.runners.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import org.sonar.api.server.debt.DebtCharacteristic; +import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; @@ -357,8 +358,13 @@ public class DebtModelOperationsTest { when(ruleDao.selectBySubCharacteristicId(2, batchSession)).thenReturn(newArrayList( new RuleDto() - .setSubCharacteristicId(2).setRemediationFunction("LINEAR_OFFSET").setRemediationCoefficient("2h").setRemediationOffset("5min") - .setDefaultSubCharacteristicId(10).setDefaultRemediationFunction("LINEAR_OFFSET").setDefaultRemediationCoefficient("4h").setDefaultRemediationOffset("15min") + .setSubCharacteristicId(2) + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) + .setRemediationCoefficient("2h").setRemediationOffset("5min") + .setDefaultSubCharacteristicId(10) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) + .setDefaultRemediationCoefficient("4h") + .setDefaultRemediationOffset("15min") )); when(dao.selectById(2, batchSession)).thenReturn(subCharacteristicDto); @@ -439,7 +445,10 @@ public class DebtModelOperationsTest { when(mybatis.openSession(true)).thenReturn(batchSession); when(ruleDao.selectBySubCharacteristicId(subCharacteristicDto.getId(), batchSession)).thenReturn(newArrayList( - new RuleDto().setSubCharacteristicId(subCharacteristicDto.getId()).setRemediationFunction("LINEAR_OFFSET").setRemediationCoefficient("2h").setRemediationOffset("5min") + new RuleDto().setSubCharacteristicId(subCharacteristicDto.getId()) + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) + .setRemediationCoefficient("2h") + .setRemediationOffset("5min") )); when(dao.selectCharacteristicsByParentId(1, batchSession)).thenReturn(newArrayList( subCharacteristicDto diff --git a/sonar-server/src/test/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexMediumTest.java b/sonar-server/src/test/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexMediumTest.java index 9b879315305..bc90b112394 100644 --- a/sonar-server/src/test/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexMediumTest.java +++ b/sonar-server/src/test/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexMediumTest.java @@ -26,6 +26,7 @@ import org.junit.Test; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; +import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.check.Cardinality; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.MyBatis; @@ -223,8 +224,8 @@ public class ActiveRuleIndexMediumTest { .setSeverity(Severity.INFO) .setCardinality(Cardinality.SINGLE) .setLanguage("js") - .setRemediationFunction("linear") - .setDefaultRemediationFunction("linear_offset") + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("1h") .setDefaultRemediationCoefficient("5d") .setRemediationOffset("5min") diff --git a/sonar-server/src/test/java/org/sonar/server/rule/RuleOperationsTest.java b/sonar-server/src/test/java/org/sonar/server/rule/RuleOperationsTest.java index ac8c9b3181f..18a5250091e 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule/RuleOperationsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule/RuleOperationsTest.java @@ -460,7 +460,9 @@ public class RuleOperationsTest { public void disable_rule_debt_when_update_rule_with_no_sub_characteristic() throws Exception { RuleDto dto = new RuleDto().setId(1).setRepositoryKey("squid").setRuleKey("UselessImportCheck") .setDefaultSubCharacteristicId(6).setDefaultRemediationFunction("LINEAR").setDefaultRemediationCoefficient("10min") - .setSubCharacteristicId(6).setRemediationFunction("CONSTANT_ISSUE").setRemediationOffset("10min"); + .setSubCharacteristicId(6) + .setRemediationFunction("CONSTANT_ISSUE") + .setRemediationOffset("10min"); RuleKey ruleKey = RuleKey.of("squid", "UselessImportCheck"); when(ruleDao.selectByKey(ruleKey, session)).thenReturn(dto); diff --git a/sonar-server/src/test/java/org/sonar/server/rule2/RuleDataMediumTest.java b/sonar-server/src/test/java/org/sonar/server/rule2/RuleDataMediumTest.java index 232125bf62e..17cbb750990 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule2/RuleDataMediumTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule2/RuleDataMediumTest.java @@ -28,6 +28,7 @@ import org.junit.Test; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; +import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.rule.RuleParamType; import org.sonar.check.Cardinality; import org.sonar.core.persistence.DbSession; @@ -243,8 +244,8 @@ public class RuleDataMediumTest { .setLanguage("js") .setTags(ImmutableSet.of("tag1", "tag2")) .setSystemTags(ImmutableSet.of("systag1", "systag2")) - .setRemediationFunction("linear") - .setDefaultRemediationFunction("linear_offset") + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("1h") .setDefaultRemediationCoefficient("5d") .setRemediationOffset("5min") diff --git a/sonar-server/src/test/java/org/sonar/server/rule2/RuleServiceMediumTest.java b/sonar-server/src/test/java/org/sonar/server/rule2/RuleServiceMediumTest.java index 3195300f532..d5bb11cffd4 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule2/RuleServiceMediumTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule2/RuleServiceMediumTest.java @@ -28,6 +28,7 @@ import org.junit.Test; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; +import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.check.Cardinality; import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.persistence.DbSession; @@ -244,7 +245,7 @@ public class RuleServiceMediumTest { // 4. Test for active rules of QProfile query = new RuleQuery() .setActivation("true") - .setqProfileKey(qprofile1.getKey().toString()); + .setQProfileKey(qprofile1.getKey().toString()); result = service.search(query, new QueryOptions()); assertThat(result.getActiveRules().values()).hasSize(2); @@ -264,8 +265,8 @@ public class RuleServiceMediumTest { .setLanguage("js") .setTags(ImmutableSet.of("tag1", "tag2")) .setSystemTags(ImmutableSet.of("systag1", "systag2")) - .setRemediationFunction("linear") - .setDefaultRemediationFunction("linear_offset") + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("1h") .setDefaultRemediationCoefficient("5d") .setRemediationOffset("5min") diff --git a/sonar-server/src/test/java/org/sonar/server/rule2/index/RuleIndexMediumTest.java b/sonar-server/src/test/java/org/sonar/server/rule2/index/RuleIndexMediumTest.java index cd963a28e73..6046b3545c6 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule2/index/RuleIndexMediumTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule2/index/RuleIndexMediumTest.java @@ -29,6 +29,7 @@ import org.junit.Test; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; +import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.check.Cardinality; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.MyBatis; @@ -443,8 +444,8 @@ public class RuleIndexMediumTest { .setSeverity(Severity.INFO) .setCardinality(Cardinality.SINGLE) .setLanguage("js") - .setRemediationFunction("LINEAR") - .setDefaultRemediationFunction("linear_offset") + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("1h") .setDefaultRemediationCoefficient("5d") .setRemediationOffset("5min") diff --git a/sonar-server/src/test/java/org/sonar/server/rule2/index/RuleFieldTest.java b/sonar-server/src/test/java/org/sonar/server/rule2/index/RuleMappingTest.java index 529364c563e..a0986074b4e 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule2/index/RuleFieldTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule2/index/RuleMappingTest.java @@ -23,7 +23,7 @@ import org.junit.Test; import static org.fest.assertions.Assertions.assertThat; -public class RuleFieldTest { +public class RuleMappingTest { @Test public void all_rule_fields() throws Exception { diff --git a/sonar-server/src/test/java/org/sonar/server/rule2/persistence/RuleDaoTest.java b/sonar-server/src/test/java/org/sonar/server/rule2/persistence/RuleDaoTest.java index 37bd788237c..bdec7a13955 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule2/persistence/RuleDaoTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule2/persistence/RuleDaoTest.java @@ -27,6 +27,7 @@ import org.junit.Test; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; import org.sonar.api.rules.Rule; +import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; import org.sonar.check.Cardinality; @@ -202,8 +203,8 @@ public class RuleDaoTest extends AbstractDaoTestCase { .setNoteUpdatedAt(DateUtils.parseDate("2013-12-20")) .setSubCharacteristicId(100) .setDefaultSubCharacteristicId(101) - .setRemediationFunction("linear") - .setDefaultRemediationFunction("linear_offset") + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("1h") .setDefaultRemediationCoefficient("5d") .setRemediationOffset("5min") @@ -238,8 +239,8 @@ public class RuleDaoTest extends AbstractDaoTestCase { .setParentId(3) .setSubCharacteristicId(100) .setDefaultSubCharacteristicId(101) - .setRemediationFunction("linear") - .setDefaultRemediationFunction("linear_offset") + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("1h") .setDefaultRemediationCoefficient("5d") .setRemediationOffset("5min") @@ -272,8 +273,8 @@ public class RuleDaoTest extends AbstractDaoTestCase { .setParentId(3) .setSubCharacteristicId(100) .setDefaultSubCharacteristicId(101) - .setRemediationFunction("linear") - .setDefaultRemediationFunction("linear_offset") + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("1h") .setDefaultRemediationCoefficient("5d") .setRemediationOffset("5min") @@ -294,8 +295,8 @@ public class RuleDaoTest extends AbstractDaoTestCase { .setParentId(null) .setSubCharacteristicId(102) .setDefaultSubCharacteristicId(103) - .setRemediationFunction("linear_offset") - .setDefaultRemediationFunction("linear") + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) .setRemediationCoefficient("5d") .setDefaultRemediationCoefficient("1h") .setRemediationOffset("10h") diff --git a/sonar-server/src/test/java/org/sonar/server/rule2/ws/RulesWebServiceTest.java b/sonar-server/src/test/java/org/sonar/server/rule2/ws/RulesWebServiceTest.java index 65d0650d347..1b8c308dc82 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule2/ws/RulesWebServiceTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule2/ws/RulesWebServiceTest.java @@ -27,6 +27,7 @@ import org.junit.Test; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; +import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.ws.WebService; import org.sonar.check.Cardinality; import org.sonar.core.persistence.DbSession; @@ -294,12 +295,12 @@ public class RulesWebServiceTest { } @Test - public void get_notes() throws Exception { + public void get_note_as_markdown_and_html() throws Exception { QualityProfileDto profile = newQualityProfile(); tester.get(QualityProfileDao.class).insert(profile, session); RuleDto rule = newRuleDto(RuleKey.of(profile.getLanguage(), "S001")) - .setNoteData("Note1"); + .setNoteData("this is *bold*"); ruleDao.insert(rule, session); session.commit(); @@ -310,7 +311,7 @@ public class RulesWebServiceTest { WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "search"); WsTester.Result result = request.execute(); - result.assertJson(this.getClass(), "get_notes.json"); + result.assertJson(this.getClass(), "get_note_as_markdown_and_html.json"); } @@ -331,8 +332,8 @@ public class RulesWebServiceTest { .setSeverity(Severity.INFO) .setCardinality(Cardinality.SINGLE) .setLanguage("js") - .setRemediationFunction("linear") - .setDefaultRemediationFunction("linear_offset") + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("1h") .setDefaultRemediationCoefficient("5d") .setRemediationOffset("5min") diff --git a/sonar-server/src/test/java/org/sonar/server/search/BaseDocTest.java b/sonar-server/src/test/java/org/sonar/server/search/BaseDocTest.java index b6536f646ee..41ad2775902 100644 --- a/sonar-server/src/test/java/org/sonar/server/search/BaseDocTest.java +++ b/sonar-server/src/test/java/org/sonar/server/search/BaseDocTest.java @@ -19,7 +19,6 @@ */ package org.sonar.server.search; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import org.junit.Test; @@ -32,30 +31,30 @@ import static org.fest.assertions.Fail.fail; public class BaseDocTest { @Test - public void get() throws Exception { - Map<String,Object> fields = Maps.newHashMap(); + public void getField() throws Exception { + Map<String, Object> fields = Maps.newHashMap(); fields.put("a_string", "foo"); fields.put("a_int", 42); fields.put("a_null", null); BaseDoc doc = new BaseDoc(fields) { }; - assertThat(doc.get("a_string")).isEqualTo("foo"); - assertThat(doc.get("a_int")).isEqualTo(42); - assertThat(doc.get("a_null")).isNull(); + assertThat(doc.getField("a_string")).isEqualTo("foo"); + assertThat(doc.getField("a_int")).isEqualTo(42); + assertThat(doc.getField("a_null")).isNull(); } @Test - public void get_fails_if_missing_field() throws Exception { - Map<String,Object> fields = Collections.emptyMap(); + public void getField_fails_if_missing_field() throws Exception { + Map<String, Object> fields = Collections.emptyMap(); BaseDoc doc = new BaseDoc(fields) { }; try { - doc.get("a_string"); + doc.getField("a_string"); fail(); } catch (IllegalStateException e) { - assertThat(e).hasMessage("Field a_string not specified in query options"); + assertThat(e).hasMessage("Field a_string not specified in query options"); } } } diff --git a/sonar-server/src/test/java/org/sonar/server/search/QueryOptionsTest.java b/sonar-server/src/test/java/org/sonar/server/search/QueryOptionsTest.java index 350712916a0..5d9b507bada 100644 --- a/sonar-server/src/test/java/org/sonar/server/search/QueryOptionsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/search/QueryOptionsTest.java @@ -21,8 +21,6 @@ package org.sonar.server.search; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; import org.junit.Test; import java.util.Arrays; @@ -44,9 +42,6 @@ public class QueryOptionsTest { options.addFieldsToReturn("four"); assertThat(options.getFieldsToReturn()).containsOnly("one", "two", "three", "four"); - - options.filterFieldsToReturn(Sets.newHashSet("one", "four", "five")); - assertThat(options.getFieldsToReturn()).containsOnly("one", "four"); } @Test @@ -61,8 +56,5 @@ public class QueryOptionsTest { options.addFieldsToReturn("four"); assertThat(options.getFieldsToReturn()).containsOnly("one", "two", "three", "four"); - - options.filterFieldsToReturn(ImmutableSet.of("one", "four", "five")); - assertThat(options.getFieldsToReturn()).containsOnly("one", "four"); } } diff --git a/sonar-server/src/test/java/org/sonar/server/ws/WsTester.java b/sonar-server/src/test/java/org/sonar/server/ws/WsTester.java index 11070abef55..ae065f5139b 100644 --- a/sonar-server/src/test/java/org/sonar/server/ws/WsTester.java +++ b/sonar-server/src/test/java/org/sonar/server/ws/WsTester.java @@ -180,6 +180,7 @@ public class WsTester { throw new IllegalStateException("Cannot find " + path); } String json = outputAsString(); + System.out.println("GOT " + json); JSONAssert.assertEquals(IOUtils.toString(url), json, strict); return this; } diff --git a/sonar-server/src/test/resources/org/sonar/server/rule2/persistence/RuleDaoTest/insert-result.xml b/sonar-server/src/test/resources/org/sonar/server/rule2/persistence/RuleDaoTest/insert-result.xml index 6ab7a822cce..0831c35492d 100644 --- a/sonar-server/src/test/resources/org/sonar/server/rule2/persistence/RuleDaoTest/insert-result.xml +++ b/sonar-server/src/test/resources/org/sonar/server/rule2/persistence/RuleDaoTest/insert-result.xml @@ -24,7 +24,7 @@ plugin_config_key="NewConfigKey" priority="0" cardinality="MULTIPLE" language="dart" created_at="2013-12-16" updated_at="2013-12-16" parent_id="3" note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" characteristic_id="100" default_characteristic_id="101" - remediation_function="linear" default_remediation_function="linear_offset" + remediation_function="LINEAR" default_remediation_function="LINEAR_OFFSET" remediation_coeff="1h" default_remediation_coeff="5d" remediation_offset="5min" default_remediation_offset="10h" effort_to_fix_description="squid.S115.effortToFix" diff --git a/sonar-server/src/test/resources/org/sonar/server/rule2/persistence/RuleDaoTest/insert_all-result.xml b/sonar-server/src/test/resources/org/sonar/server/rule2/persistence/RuleDaoTest/insert_all-result.xml index 91b6dae1d04..7001c17804c 100644 --- a/sonar-server/src/test/resources/org/sonar/server/rule2/persistence/RuleDaoTest/insert_all-result.xml +++ b/sonar-server/src/test/resources/org/sonar/server/rule2/persistence/RuleDaoTest/insert_all-result.xml @@ -24,7 +24,7 @@ plugin_config_key="NewConfigKey" priority="0" cardinality="MULTIPLE" language="dart" created_at="2013-12-16" updated_at="2013-12-16" parent_id="3" note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" characteristic_id="100" default_characteristic_id="101" - remediation_function="linear" default_remediation_function="linear_offset" + remediation_function="LINEAR" default_remediation_function="LINEAR_OFFSET" remediation_coeff="1h" default_remediation_coeff="5d" remediation_offset="5min" default_remediation_offset="10h" effort_to_fix_description="squid.S115.effortToFix" @@ -34,7 +34,7 @@ plugin_config_key="NewConfigKey2" priority="2" cardinality="SINGLE" language="js" created_at="2013-12-16" updated_at="2013-12-16" parent_id="[null]" note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]" characteristic_id="102" default_characteristic_id="103" - remediation_function="linear_offset" default_remediation_function="linear" + remediation_function="LINEAR_OFFSET" default_remediation_function="LINEAR" remediation_coeff="5d" default_remediation_coeff="1h" remediation_offset="10h" default_remediation_offset="5min" effort_to_fix_description="squid.S115.effortToFix2" diff --git a/sonar-server/src/test/resources/org/sonar/server/rule2/persistence/RuleDaoTest/update-result.xml b/sonar-server/src/test/resources/org/sonar/server/rule2/persistence/RuleDaoTest/update-result.xml index 19677c9a918..0c71afe4b9b 100644 --- a/sonar-server/src/test/resources/org/sonar/server/rule2/persistence/RuleDaoTest/update-result.xml +++ b/sonar-server/src/test/resources/org/sonar/server/rule2/persistence/RuleDaoTest/update-result.xml @@ -4,7 +4,7 @@ plugin_config_key="NewConfigKey" priority="0" cardinality="MULTIPLE" language="dart" created_at="2011-04-25 01:05:00" updated_at="2014-01-01" parent_id="3" note_data="My note" note_user_login="admin" note_created_at="2013-12-19" note_updated_at="2013-12-20" characteristic_id="100" default_characteristic_id="101" - remediation_function="linear" default_remediation_function="linear_offset" + remediation_function="LINEAR" default_remediation_function="LINEAR_OFFSET" remediation_coeff="1h" default_remediation_coeff="5d" remediation_offset="5min" default_remediation_offset="10h" effort_to_fix_description="squid.S115.effortToFix" diff --git a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/get_note_as_markdown_and_html.json b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/get_note_as_markdown_and_html.json new file mode 100644 index 00000000000..ea1df5579a3 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/get_note_as_markdown_and_html.json @@ -0,0 +1,21 @@ +{"total": 1, "p": 1, "ps": 25, "rules": [ + { + "key": "java:S001", + "repo": "java", + "name": "Rule S001", + "lang": "js", + "htmlDesc": "Description S001", + "status": "READY", + "severity": "INFO", + "template": false, + "internalKey": "InternalKeyS001", + "mdNote": "this is *bold*", + "htmlNote": "this is <em>bold</em>", + "tags": [], + "sysTags": [], + "debtRemFnType": "LINEAR", + "debtRemFnCoeff": "1h", + "debtRemFnOffset": "5min", + "params": [] + } +], "actives": {}} diff --git a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/get_notes.json b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/get_notes.json deleted file mode 100644 index 13083db4376..00000000000 --- a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/get_notes.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "p": 1, - "ps": 25, - "rules": [ - { - "actives": [], - "debtRemediationFunctionCoefficient": "1h", - "debtRemediationFunctionOffset": "5min", - "debtRemediationFunctionType": "LINEAR", - "htmlDesc": "Description S001", - "internalKey": "InternalKeyS001", - "key": "java:S001", - "lang": "js", - "markdownNote": "Note1", - "name": "Rule S001", - "params": [], - "repo": "java", - "severity": "INFO", - "status": "READY", - "sysTags": [], - "tags": [], - "template": false - } - ], - "total": 1 -} diff --git a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_2_rules.json b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_2_rules.json index 873652cb513..0f18abaeb47 100644 --- a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_2_rules.json +++ b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_2_rules.json @@ -1,38 +1,36 @@ {"total": 2, "p": 1, "ps": 25, "rules": [ { - "key": "javascript:S001", + "key": "javascript:S002", "repo": "javascript", + "name": "Rule S002", "lang": "js", + "htmlDesc": "Description S002", + "status": "READY", + "severity": "INFO", + "template": false, + "internalKey": "InternalKeyS002", + "tags": [], + "sysTags": [], + "debtRemFnType": "LINEAR", + "debtRemFnCoeff": "1h", + "debtRemFnOffset": "5min", + "params": [] + }, + { + "key": "javascript:S001", + "repo": "javascript", "name": "Rule S001", + "lang": "js", "htmlDesc": "Description S001", "status": "READY", + "severity": "INFO", "template": false, "internalKey": "InternalKeyS001", - "severity": "INFO", "tags": [], "sysTags": [], - "debtRemediationFunctionType": "LINEAR", - "debtRemediationFunctionCoefficient": "1h", - "debtRemediationFunctionOffset": "5min", - "params": [], - "actives": [] - }, - { - "key": "javascript:S002", - "repo": "javascript", - "lang": "js", - "name": "Rule S002", - "htmlDesc": "Description S002", - "status": "READY", - "template": false, - "internalKey": "InternalKeyS002", - "severity": "INFO", - "tags": [], - "sysTags": [], - "debtRemediationFunctionType": "LINEAR", - "debtRemediationFunctionCoefficient": "1h", - "debtRemediationFunctionOffset": "5min", - "params": [], - "actives": [] - } -]} + "debtRemFnType": "LINEAR", + "debtRemFnCoeff": "1h", + "debtRemFnOffset": "5min", + "params": [] + } +], "actives": {}} diff --git a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_active_rules.json b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_active_rules.json index df474318c31..68cfa284c66 100644 --- a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_active_rules.json +++ b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_active_rules.json @@ -1,27 +1,28 @@ {"total": 1, "p": 1, "ps": 25, "rules": [ + { + "key": "java:S001", + "repo": "java", + "name": "Rule S001", + "lang": "js", + "htmlDesc": "Description S001", + "status": "READY", + "severity": "INFO", + "template": false, + "internalKey": "InternalKeyS001", + "tags": [], + "sysTags": [], + "debtRemFnType": "LINEAR", + "debtRemFnCoeff": "1h", + "debtRemFnOffset": "5min", + "params": [] + } +], "actives": { + "java:S001": [ { - "key": "java:S001", - "repo": "java", - "lang": "js", - "name": "Rule S001", - "htmlDesc": "Description S001", - "status": "READY", - "template": false, - "internalKey": "InternalKeyS001", - "severity": "INFO", - "tags": [], - "sysTags": [], - "debtRemediationFunctionType": "LINEAR", - "debtRemediationFunctionCoefficient": "1h", - "debtRemediationFunctionOffset": "5min", - "params": [], - "actives": [ - { - "key": "My Profile:java:java:S001", - "inherit": "NONE", - "severity": "BLOCKER", - "params": [] - } - ] + "qProfile": "My Profile:java", + "inherit": "NONE", + "severity": "BLOCKER", + "params": [] } -]} + ] +}} diff --git a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_active_rules_params.json b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_active_rules_params.json index f0fa30a25fb..fc30d831d06 100644 --- a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_active_rules_params.json +++ b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_active_rules_params.json @@ -1,52 +1,48 @@ -{ - "p": 1, - "ps": 25, - "rules": [ +{"total": 1, "p": 1, "ps": 25, "rules": [ + { + "key": "java:S001", + "repo": "java", + "name": "Rule S001", + "lang": "js", + "htmlDesc": "Description S001", + "status": "READY", + "severity": "INFO", + "template": false, + "internalKey": "InternalKeyS001", + "tags": [], + "sysTags": [], + "debtRemFnType": "LINEAR", + "debtRemFnCoeff": "1h", + "debtRemFnOffset": "5min", + "params": [ + { + "key": "my_var", + "desc": "My small description", + "defaultValue": "some value" + }, + { + "key": "the_var", + "desc": "My small description", + "defaultValue": "other value" + } + ] + } +], "actives": { + "java:S001": [ + { + "qProfile": "My Profile:java", + "inherit": "NONE", + "severity": "BLOCKER", + "params": [ { - "actives": [ - { - "inherit": "NONE", - "key": "My Profile:java:java:S001", - "params": [ - { - "key": "the_var", - "value": "The Other Value" - }, - { - "key": "my_var", - "value": "The VALUE" - } - ], - "severity": "BLOCKER" - } - ], - "debtRemediationFunctionCoefficient": "1h", - "debtRemediationFunctionOffset": "5min", - "debtRemediationFunctionType": "LINEAR", - "htmlDesc": "Description S001", - "internalKey": "InternalKeyS001", - "key": "java:S001", - "lang": "js", - "name": "Rule S001", - "params": [ - { - "defaultValue": "some value", - "desc": "My small description", - "key": "my_var" - }, - { - "defaultValue": "other value", - "desc": "My small description", - "key": "the_var" - } - ], - "repo": "java", - "severity": "INFO", - "status": "READY", - "sysTags": [], - "tags": [], - "template": false + "key": "the_var", + "value": "The Other Value" + }, + { + "key": "my_var", + "value": "The VALUE" } - ], - "total": 1 -} + ] + } + ] +}} diff --git a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_debt_rule.json b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_debt_rule.json index 58ae5c93514..30da25759e3 100644 --- a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_debt_rule.json +++ b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_debt_rule.json @@ -1,21 +1,20 @@ {"total": 1, "p": 1, "ps": 25, "rules": [ - { - "key": "javascript:S001", - "repo": "javascript", - "lang": "js", - "name": "Rule S001", - "htmlDesc": "Description S001", - "status": "READY", - "template": false, - "internalKey": "InternalKeyS001", - "severity": "INFO", - "tags": [], - "sysTags": [], - "debtSubCharacteristicKey": "1", - "debtRemediationFunctionType": "LINEAR", - "debtRemediationFunctionCoefficient": "1h", - "debtRemediationFunctionOffset": "5min", - "params": [], - "actives": [] - } -]} + { + "key": "javascript:S001", + "repo": "javascript", + "name": "Rule S001", + "lang": "js", + "htmlDesc": "Description S001", + "status": "READY", + "severity": "INFO", + "template": false, + "internalKey": "InternalKeyS001", + "tags": [], + "sysTags": [], + "debtSubChar": "1", + "debtRemFnType": "LINEAR", + "debtRemFnCoeff": "1h", + "debtRemFnOffset": "5min", + "params": [] + } +], "actives": {}} diff --git a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_no_active_rules.json b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_no_active_rules.json index 592701ef71d..89bd88aace0 100644 --- a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_no_active_rules.json +++ b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_no_active_rules.json @@ -1,20 +1,19 @@ {"total": 1, "p": 1, "ps": 25, "rules": [ - { - "key": "java:S001", - "repo": "java", - "lang": "js", - "name": "Rule S001", - "htmlDesc": "Description S001", - "status": "READY", - "template": false, - "internalKey": "InternalKeyS001", - "severity": "INFO", - "tags": [], - "sysTags": [], - "debtRemediationFunctionType": "LINEAR", - "debtRemediationFunctionCoefficient": "1h", - "debtRemediationFunctionOffset": "5min", - "params": [], - "actives": [] - } -]} + { + "key": "java:S001", + "repo": "java", + "name": "Rule S001", + "lang": "js", + "htmlDesc": "Description S001", + "status": "READY", + "severity": "INFO", + "template": false, + "internalKey": "InternalKeyS001", + "tags": [], + "sysTags": [], + "debtRemFnType": "LINEAR", + "debtRemFnCoeff": "1h", + "debtRemFnOffset": "5min", + "params": [] + } +], "actives": {}} diff --git a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_no_rules.json b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_no_rules.json index 8c492f5d4b2..9aed4375270 100644 --- a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_no_rules.json +++ b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_no_rules.json @@ -1 +1,7 @@ -{"total":0,"p":1,"ps":25,"rules":[]}
\ No newline at end of file +{ + "total": 0, + "p": 1, + "ps": 25, + "rules": [], + "actives": {} +} diff --git a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_profile_active_rules.json b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_profile_active_rules.json index ee43cf79949..b91bcb245d2 100644 --- a/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_profile_active_rules.json +++ b/sonar-server/src/test/resources/org/sonar/server/rule2/ws/RulesWebServiceTest/search_profile_active_rules.json @@ -1,32 +1,34 @@ { - "p": 1, - "ps": 25, - "rules": [ - { - "actives": [ - { - "inherit": "NONE", - "key": "p2:java:java:S001", - "params": [], - "severity": "BLOCKER" - } - ], - "debtRemediationFunctionCoefficient": "1h", - "debtRemediationFunctionOffset": "5min", - "debtRemediationFunctionType": "LINEAR", - "htmlDesc": "Description S001", - "internalKey": "InternalKeyS001", - "key": "java:S001", - "lang": "js", - "name": "Rule S001", - "params": [], - "repo": "java", - "severity": "INFO", - "status": "READY", - "sysTags": [], - "tags": [], - "template": false - } - ], - "total": 1 + "total": 1, + "p": 1, + "ps": 25, + "rules": [ + { + "key": "java:S001", + "repo": "java", + "name": "Rule S001", + "lang": "js", + "htmlDesc": "Description S001", + "status": "READY", + "severity": "INFO", + "template": false, + "internalKey": "InternalKeyS001", + "tags": [], + "sysTags": [], + "debtRemFnType": "LINEAR", + "debtRemFnCoeff": "1h", + "debtRemFnOffset": "5min", + "params": [] + } + ], + "actives": { + "java:S001": [ + { + "qProfile": "p2:java", + "inherit": "NONE", + "severity": "BLOCKER", + "params": [] + } + ] + } } |