import org.elasticsearch.common.collect.Maps;
import org.elasticsearch.common.joda.time.format.ISODateTimeFormat;
import org.sonar.server.rule.Rule;
+import org.sonar.server.rule.RuleDocumentParser;
import org.sonar.server.rule.RuleNote;
import org.sonar.server.rule.RuleParam;
import javax.annotation.CheckForNull;
+import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
private final RuleNote activeRuleNote;
private final List<QProfileRuleParam> params;
+ // TODO move this in a parser class
public QProfileRule(Map<String, Object> ruleSource, Map<String, Object> activeRuleSource) {
-
- rule = new Rule(ruleSource);
-
+ rule = RuleDocumentParser.parse(ruleSource);
if (activeRuleSource.isEmpty()) {
activeRuleId = null;
severity = (String) ruleSource.get(ActiveRuleDocument.FIELD_SEVERITY);
activeRuleNote = new RuleNote(
(String) ruleNoteDocument.get(ActiveRuleDocument.FIELD_NOTE_DATA),
(String) ruleNoteDocument.get(ActiveRuleDocument.FIELD_NOTE_USER_LOGIN),
- Rule.parseOptionalDate(ActiveRuleDocument.FIELD_NOTE_CREATED_AT, ruleNoteDocument),
- Rule.parseOptionalDate(ActiveRuleDocument.FIELD_NOTE_UPDATED_AT, ruleNoteDocument)
+ RuleDocumentParser.parseOptionalDate(ActiveRuleDocument.FIELD_NOTE_CREATED_AT, ruleNoteDocument),
+ RuleDocumentParser.parseOptionalDate(ActiveRuleDocument.FIELD_NOTE_UPDATED_AT, ruleNoteDocument)
);
} else {
activeRuleNote = null;
}
public String key() {
- return rule.key();
+ return rule.ruleKey().rule();
}
public String repositoryKey() {
- return rule.repositoryKey();
+ return rule.ruleKey().repository();
}
public String language() {
return rule.ruleNote();
}
- public List<String> systemTags() {
+ public Collection<String> systemTags() {
return rule.systemTags();
}
- public List<String> adminTags() {
+ public Collection<String> adminTags() {
return rule.adminTags();
}
*/
package org.sonar.server.rule;
-import org.elasticsearch.common.collect.Lists;
-import org.elasticsearch.common.collect.Maps;
-import org.elasticsearch.common.joda.time.format.ISODateTimeFormat;
import org.sonar.api.rule.RuleKey;
-import org.sonar.api.server.rule.RuleParamType;
import org.sonar.check.Cardinality;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import static com.google.common.collect.Lists.newArrayList;
public class Rule {
private int id;
- private String key;
+ private RuleKey ruleKey;
private String language;
private String name;
private String description;
- private Integer templateId;
- private String repositoryKey;
private String severity;
private String status;
private String cardinality;
+ private Integer templateId;
+ private RuleNote ruleNote;
+ private Collection<String> systemTags;
+ private Collection<String> adminTags;
+ private Collection<RuleParam> params;
private Date createdAt;
private Date updatedAt;
- private List<String> systemTags;
- private List<String> adminTags;
- private RuleNote ruleNote;
- private List<RuleParam> params;
-
- /**
- * Used to create manual rule
- */
- public Rule(String key, String name, String description, String repositoryKey, String severity, String status, Date createdAt, Date updatedAt) {
- this.key = key;
- this.name = name;
- this.description = description;
- this.repositoryKey = repositoryKey;
- this.severity = severity;
- this.status = status;
- this.createdAt = createdAt;
- this.updatedAt = updatedAt;
- this.systemTags = newArrayList();
- this.adminTags = newArrayList();
-
- }
-
- public Rule(Map<String, Object> ruleSource) {
- id = (Integer) ruleSource.get(RuleDocument.FIELD_ID);
- key = (String) ruleSource.get(RuleDocument.FIELD_KEY);
- language = (String) ruleSource.get(RuleDocument.FIELD_LANGUAGE);
- repositoryKey = (String) ruleSource.get(RuleDocument.FIELD_REPOSITORY_KEY);
- severity = (String) ruleSource.get(RuleDocument.FIELD_SEVERITY);
- name = (String) ruleSource.get(RuleDocument.FIELD_NAME);
- description = (String) ruleSource.get(RuleDocument.FIELD_DESCRIPTION);
- status = (String) ruleSource.get(RuleDocument.FIELD_STATUS);
- cardinality = (String) ruleSource.get("cardinality");
- templateId = (Integer) ruleSource.get(RuleDocument.FIELD_TEMPLATE_ID);
- createdAt = parseOptionalDate(RuleDocument.FIELD_CREATED_AT, ruleSource);
- updatedAt = parseOptionalDate(RuleDocument.FIELD_UPDATED_AT, ruleSource);
-
- if (ruleSource.containsKey(RuleDocument.FIELD_NOTE)) {
- Map<String, Object> ruleNoteDocument = (Map<String, Object>) ruleSource.get(RuleDocument.FIELD_NOTE);
- ruleNote = new RuleNote(
- (String) ruleNoteDocument.get(RuleDocument.FIELD_NOTE_DATA),
- (String) ruleNoteDocument.get(RuleDocument.FIELD_NOTE_USER_LOGIN),
- parseOptionalDate(RuleDocument.FIELD_NOTE_CREATED_AT, ruleNoteDocument),
- parseOptionalDate(RuleDocument.FIELD_NOTE_UPDATED_AT, ruleNoteDocument)
- );
- } else {
- ruleNote = null;
- }
-
- params = Lists.newArrayList();
- if (ruleSource.containsKey(RuleDocument.FIELD_PARAMS)) {
- Map<String, Map<String, Object>> ruleParams = Maps.newHashMap();
- for (Map<String, Object> ruleParam: (List<Map<String, Object>>) ruleSource.get(RuleDocument.FIELD_PARAMS)) {
- ruleParams.put((String) ruleParam.get(RuleDocument.FIELD_PARAM_KEY), ruleParam);
- }
- for(Map.Entry<String, Map<String, Object>> ruleParam: ruleParams.entrySet()) {
- RuleParamType type = RuleParamType.parse((String) ruleParam.getValue().get(RuleDocument.FIELD_PARAM_TYPE));
- params.add(new RuleParam(
- (String) ruleParam.getValue().get(RuleDocument.FIELD_PARAM_KEY),
- (String) ruleParam.getValue().get(RuleDocument.FIELD_PARAM_DESCRIPTION),
- (String) ruleParam.getValue().get(RuleDocument.FIELD_PARAM_DEFAULT_VALUE),
- type
- ));
- }
- }
-
- systemTags = Lists.newArrayList();
- if (ruleSource.containsKey(RuleDocument.FIELD_SYSTEM_TAGS)) {
- for (String tag: (List<String>) ruleSource.get(RuleDocument.FIELD_SYSTEM_TAGS)) {
- systemTags.add(tag);
- }
- }
- adminTags = Lists.newArrayList();
- if (ruleSource.containsKey(RuleDocument.FIELD_ADMIN_TAGS)) {
- for (String tag: (List<String>) ruleSource.get(RuleDocument.FIELD_ADMIN_TAGS)) {
- adminTags.add(tag);
- }
- }
+
+ private Rule(Builder builder) {
+ this.id = builder.id;
+ this.ruleKey = RuleKey.of(builder.repositoryKey, builder.key);
+ this.language = builder.language;
+ this.name = builder.name;
+ this.description = builder.description;
+ this.severity = builder.severity;
+ this.status = builder.status;
+ this.cardinality = builder.cardinality;
+ this.templateId = builder.templateId;
+ this.ruleNote = builder.ruleNote;
+ this.systemTags = defaultCollection(builder.systemTags);
+ this.adminTags = defaultCollection(builder.adminTags);
+ this.params = defaultCollection(builder.params);
+ this.createdAt = builder.createdAt;
+ this.updatedAt = builder.updatedAt;
}
public int id() {
return id;
}
- public String key() {
- return key;
- }
-
- public String repositoryKey() {
- return repositoryKey;
+ public RuleKey ruleKey() {
+ return ruleKey;
}
public String language() {
return description;
}
+ public String severity() {
+ return severity;
+ }
+
public String status() {
return status;
}
- public Date createdAt() {
- return createdAt;
+ public String cardinality() {
+ return cardinality;
}
@CheckForNull
- public Date updatedAt() {
- return updatedAt;
+ public Integer templateId() {
+ return templateId;
}
@CheckForNull
- public Integer templateId() {
- return templateId;
+ public RuleNote ruleNote() {
+ return ruleNote;
+ }
+
+ public Collection<String> systemTags() {
+ return systemTags;
+ }
+
+ public Collection<String> adminTags() {
+ return adminTags;
+ }
+
+ public Collection<RuleParam> params() {
+ return params;
+ }
+
+ public Date createdAt() {
+ return createdAt;
}
public boolean isTemplate() {
return templateId != null;
}
- public String severity() {
- return severity;
+ @CheckForNull
+ public Date updatedAt() {
+ return updatedAt;
}
- public static Date parseOptionalDate(String field, Map<String, Object> ruleSource) {
- String dateValue = (String) ruleSource.get(field);
- if (dateValue == null) {
- return null;
- } else {
- return ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(dateValue).toDate();
+ public static class Builder {
+
+ private int id;
+ private String key;
+ private String repositoryKey;
+ private String language;
+ private String name;
+ private String description;
+ private String severity;
+ private String status;
+ private String cardinality;
+ private Integer templateId;
+ private RuleNote ruleNote;
+ private Collection<String> systemTags;
+ private Collection<String> adminTags;
+ private Collection<RuleParam> params;
+ private Date createdAt;
+ private Date updatedAt;
+
+ public Builder setId(int id) {
+ this.id = id;
+ return this;
}
- }
- @CheckForNull
- public RuleNote ruleNote() {
- return ruleNote;
- }
+ public Builder setKey(String key) {
+ this.key = key;
+ return this;
+ }
- public List<String> systemTags() {
- return systemTags;
- }
+ public Builder setRepositoryKey(String repositoryKey) {
+ this.repositoryKey = repositoryKey;
+ return this;
+ }
- public List<String> adminTags() {
- return adminTags;
- }
+ public Builder setLanguage(String language) {
+ this.language = language;
+ return this;
+ }
- public List<RuleParam> params() {
- return params;
+ public Builder setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public Builder setDescription(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public Builder setSeverity(String severity) {
+ this.severity = severity;
+ return this;
+ }
+
+ public Builder setStatus(String status) {
+ this.status = status;
+ return this;
+ }
+
+ public Builder setCardinality(String cardinality) {
+ this.cardinality = cardinality;
+ return this;
+ }
+
+ public Builder setTemplateId(@Nullable Integer templateId) {
+ this.templateId = templateId;
+ return this;
+ }
+
+ public Builder setRuleNote(@Nullable RuleNote ruleNote) {
+ this.ruleNote = ruleNote;
+ return this;
+ }
+
+ public Builder setSystemTags(Collection<String> systemTags) {
+ this.systemTags = systemTags;
+ return this;
+ }
+
+ public Builder setAdminTags(Collection<String> adminTags) {
+ this.adminTags = adminTags;
+ return this;
+ }
+
+ public Builder setParams(Collection<RuleParam> params) {
+ this.params = params;
+ return this;
+ }
+
+ public Builder setCreatedAt(Date createdAt) {
+ this.createdAt = createdAt;
+ return this;
+ }
+
+ public Builder setUpdatedAt(@Nullable Date updatedAt) {
+ this.updatedAt = updatedAt;
+ return this;
+ }
+
+ public Rule build() {
+ // TODO Add validation on mandatory key, repokey, ...
+ return new Rule(this);
+ }
}
- public RuleKey ruleKey() {
- return RuleKey.of(repositoryKey, key);
+ private static <T> Collection<T> defaultCollection(@Nullable Collection<T> c) {
+ return c == null ? Collections.<T>emptyList() : Collections.unmodifiableCollection(c);
}
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.rule;
+
+import org.elasticsearch.common.collect.Lists;
+import org.elasticsearch.common.collect.Maps;
+import org.elasticsearch.common.joda.time.format.ISODateTimeFormat;
+import org.sonar.api.server.rule.RuleParamType;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+public class RuleDocumentParser {
+
+ public static Rule parse(Map<String, Object> ruleSource) {
+ Rule.Builder ruleBuilder = new Rule.Builder();
+
+ ruleBuilder.setId((Integer) ruleSource.get(RuleDocument.FIELD_ID));
+ ruleBuilder.setKey((String) ruleSource.get(RuleDocument.FIELD_KEY));
+ ruleBuilder.setLanguage((String) ruleSource.get(RuleDocument.FIELD_LANGUAGE));
+ ruleBuilder.setRepositoryKey((String) ruleSource.get(RuleDocument.FIELD_REPOSITORY_KEY));
+ ruleBuilder.setSeverity((String) ruleSource.get(RuleDocument.FIELD_SEVERITY));
+ ruleBuilder.setName((String) ruleSource.get(RuleDocument.FIELD_NAME));
+ ruleBuilder.setDescription((String) ruleSource.get(RuleDocument.FIELD_DESCRIPTION));
+ ruleBuilder.setStatus((String) ruleSource.get(RuleDocument.FIELD_STATUS));
+ ruleBuilder.setCardinality((String) ruleSource.get("cardinality"));
+ ruleBuilder.setTemplateId((Integer) ruleSource.get(RuleDocument.FIELD_TEMPLATE_ID));
+ ruleBuilder.setCreatedAt(parseOptionalDate(RuleDocument.FIELD_CREATED_AT, ruleSource));
+ ruleBuilder.setUpdatedAt(parseOptionalDate(RuleDocument.FIELD_UPDATED_AT, ruleSource));
+
+ if (ruleSource.containsKey(RuleDocument.FIELD_NOTE)) {
+ Map<String, Object> ruleNoteDocument = (Map<String, Object>) ruleSource.get(RuleDocument.FIELD_NOTE);
+ ruleBuilder.setRuleNote(new RuleNote(
+ (String) ruleNoteDocument.get(RuleDocument.FIELD_NOTE_DATA),
+ (String) ruleNoteDocument.get(RuleDocument.FIELD_NOTE_USER_LOGIN),
+ parseOptionalDate(RuleDocument.FIELD_NOTE_CREATED_AT, ruleNoteDocument),
+ parseOptionalDate(RuleDocument.FIELD_NOTE_UPDATED_AT, ruleNoteDocument)
+ ));
+ }
+
+ List<RuleParam> params = Lists.newArrayList();
+ if (ruleSource.containsKey(RuleDocument.FIELD_PARAMS)) {
+ Map<String, Map<String, Object>> ruleParams = Maps.newHashMap();
+ for (Map<String, Object> ruleParam: (List<Map<String, Object>>) ruleSource.get(RuleDocument.FIELD_PARAMS)) {
+ ruleParams.put((String) ruleParam.get(RuleDocument.FIELD_PARAM_KEY), ruleParam);
+ }
+ for(Map.Entry<String, Map<String, Object>> ruleParam: ruleParams.entrySet()) {
+ RuleParamType type = RuleParamType.parse((String) ruleParam.getValue().get(RuleDocument.FIELD_PARAM_TYPE));
+ params.add(new RuleParam(
+ (String) ruleParam.getValue().get(RuleDocument.FIELD_PARAM_KEY),
+ (String) ruleParam.getValue().get(RuleDocument.FIELD_PARAM_DESCRIPTION),
+ (String) ruleParam.getValue().get(RuleDocument.FIELD_PARAM_DEFAULT_VALUE),
+ type
+ ));
+ }
+ }
+ ruleBuilder.setParams(params);
+
+ List<String> systemTags = newArrayList();
+ if (ruleSource.containsKey(RuleDocument.FIELD_SYSTEM_TAGS)) {
+ for (String tag: (List<String>) ruleSource.get(RuleDocument.FIELD_SYSTEM_TAGS)) {
+ systemTags.add(tag);
+ }
+ }
+ ruleBuilder.setSystemTags(systemTags);
+
+ List<String> adminTags = newArrayList();
+ if (ruleSource.containsKey(RuleDocument.FIELD_ADMIN_TAGS)) {
+ for (String tag: (List<String>) ruleSource.get(RuleDocument.FIELD_ADMIN_TAGS)) {
+ adminTags.add(tag);
+ }
+ }
+ ruleBuilder.setAdminTags(adminTags);
+
+ return ruleBuilder.build();
+ }
+
+ public static Date parseOptionalDate(String field, Map<String, Object> ruleSource) {
+ String dateValue = (String) ruleSource.get(field);
+ if (dateValue == null) {
+ return null;
+ } else {
+ return ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(dateValue).toDate();
+ }
+ }
+}
+
if (hits.totalHits() == 0) {
return null;
} else {
- return new Rule(hits.hits()[0].sourceAsMap());
+ return RuleDocumentParser.parse(hits.hits()[0].sourceAsMap());
}
}
if (ruleKey.repository().equals("manual")) {
org.sonar.api.rules.Rule rule = ruleFinder.findByKey(ruleKey);
if (rule != null) {
- return new Rule(rule.getKey(), rule.getName(), rule.getDescription(), rule.getRepositoryKey(), rule.getSeverity().name(), rule.getStatus(),
- rule.getCreatedAt(), rule.getUpdatedAt());
+ return new Rule.Builder()
+ .setKey(rule.getKey())
+ .setRepositoryKey(rule.getRepositoryKey())
+ .setName(rule.getName())
+ .setDescription(rule.getDescription())
+ .setSeverity(rule.getSeverity().name())
+ .setStatus(rule.getStatus())
+ .setCreatedAt(rule.getCreatedAt())
+ .setUpdatedAt(rule.getUpdatedAt()).build();
}
return null;
} else {
assertThat(esSetup.client().admin().indices().prepareTypesExists("rules").setTypes("rule").execute().actionGet().isExists()).isTrue();
}
-
@Test
public void should_find_rule_by_key() {
assertThat(registry.findByKey(RuleKey.of("unknown", "RuleWithParameters"))).isNull();
assertThat(registry.findByKey(RuleKey.of("xoo", "unknown"))).isNull();
final Rule rule = registry.findByKey(RuleKey.of("xoo", "RuleWithParameters"));
assertThat(rule).isNotNull();
- assertThat(rule.repositoryKey()).isEqualTo("xoo");
- assertThat(rule.key()).isEqualTo("RuleWithParameters");
+ assertThat(rule.ruleKey().repository()).isEqualTo("xoo");
+ assertThat(rule.ruleKey().rule()).isEqualTo("RuleWithParameters");
assertThat(rule.params()).hasSize(5);
assertThat(rule.adminTags()).hasSize(1);
assertThat(rule.systemTags()).hasSize(2);
}
-
@Test
public void should_filter_removed_rules() {
assertThat(registry.findIds(new HashMap<String, String>())).containsOnly(1, 2);
@Mock
I18n i18n;
+ Rule.Builder ruleBuilder = new Rule.Builder()
+ .setKey("AvoidCycle")
+ .setRepositoryKey("squid")
+ .setName("Avoid cycle")
+ .setDescription("Avoid cycle between packages");
+
WsTester tester;
@Before
@Test
public void show_rule() throws Exception {
String ruleKey = "squid:AvoidCycle";
- Rule rule = createStandardRule();
+ Rule rule = ruleBuilder.build();
when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(rule);
}
@Test
- public void return_not_found_on_unkwown_rule() throws Exception {
+ public void return_not_found_on_unknown_rule() throws Exception {
String ruleKey = "squid:AvoidCycle";
when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(null);
public void show_rule_with_dates() throws Exception {
Date date1 = DateUtils.parseDateTime("2014-01-22T19:10:03+0100");
Date date2 = DateUtils.parseDateTime("2014-01-23T19:10:03+0100");
- Rule rule = createStandardRule();
- when(rule.createdAt()).thenReturn(date1);
- when(rule.updatedAt()).thenReturn(date2);
+ Rule rule = ruleBuilder
+ .setCreatedAt(date1)
+ .setUpdatedAt(date2)
+ .build();
when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(rule);
when(i18n.formatDateTime(any(Locale.class), eq(date1))).thenReturn("Jan 22, 2014 10:03 AM");
@Test
public void show_rule_with_note() throws Exception {
- Rule rule = createStandardRule();
RuleNote note = mock(RuleNote.class);
when(note.data()).thenReturn("*Extended rule description*");
- when(rule.ruleNote()).thenReturn(note);
+ Rule rule = ruleBuilder
+ .setRuleNote(note)
+ .build();
when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(rule);
@Test
public void show_rule_with_tags() throws Exception {
- Rule rule = createStandardRule();
- when(rule.adminTags()).thenReturn(ImmutableList.of("complexity"));
- when(rule.systemTags()).thenReturn(ImmutableList.of("security"));
+ Rule rule = ruleBuilder
+ .setAdminTags(ImmutableList.of("complexity"))
+ .setSystemTags(ImmutableList.of("security"))
+ .build();
when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(rule);
}
}
- private Rule create(String repoKey, String key, String name, String description) {
- Rule mockRule = mock(Rule.class);
- when(mockRule.repositoryKey()).thenReturn(repoKey);
- when(mockRule.key()).thenReturn(key);
- when(mockRule.ruleKey()).thenReturn(RuleKey.of(repoKey, key));
- when(mockRule.name()).thenReturn(name);
- when(mockRule.description()).thenReturn(description);
- return mockRule;
- }
-
- private Rule createStandardRule() {
- return create("squid", "AvoidCycle", "Avoid cycle", "Avoid cycle between packages");
- }
}