diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2013-04-17 18:29:35 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2013-04-17 18:36:56 +0200 |
commit | 7660b174b186527b5df5354295886c42dec2109d (patch) | |
tree | 0ed5f14607232f9161741a486e5d67ca48440e93 /sonar-plugin-api | |
parent | 398c82a5810e446a22b31d204a87ad7fd806a068 (diff) | |
download | sonarqube-7660b174b186527b5df5354295886c42dec2109d.tar.gz sonarqube-7660b174b186527b5df5354295886c42dec2109d.zip |
SONAR-3755 support the parameter "rules" in /api/issues/search
Diffstat (limited to 'sonar-plugin-api')
7 files changed, 304 insertions, 69 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueChange.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueChange.java new file mode 100644 index 00000000000..1587ca25453 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueChange.java @@ -0,0 +1,146 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.api.issue; + +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @since 3.6 + */ +public class IssueChange { + private String severity = null; + private String comment = null; + private Boolean manualSeverity = null; + private String message = null; + private boolean lineChanged = false; + private Integer line = null; + private boolean costChanged = false; + private Double cost = null; + private String resolution = null; + private boolean assigneeLoginChanged = false; + private String assigneeLogin = null; + private Map<String, String> attributes = null; + + private IssueChange() { + } + + public static IssueChange create() { + return new IssueChange(); + } + + public boolean hasChanges() { + return severity != null || comment != null || manualSeverity != null || message != null || + lineChanged || costChanged || resolution != null || assigneeLoginChanged || attributes != null; + } + + public IssueChange setSeverity(String severity) { + this.severity = severity; + return this; + } + + public IssueChange setComment(String comment) { + this.comment = comment; + return this; + } + + public IssueChange setManualSeverity(boolean b) { + this.manualSeverity = b; + return this; + } + + public IssueChange setMessage(String message) { + this.message = message; + return this; + } + + public IssueChange setLine(@Nullable Integer line) { + this.lineChanged = true; + this.line = line; + return this; + } + + public IssueChange setCost(@Nullable Double cost) { + this.costChanged = true; + this.cost = cost; + return this; + } + + public IssueChange setResolution(String resolution) { + this.resolution = resolution; + return this; + } + + public IssueChange setAssigneeLogin(@Nullable String assigneeLogin) { + this.assigneeLoginChanged = true; + this.assigneeLogin = assigneeLogin; + return this; + } + + public IssueChange setAttribute(String key, @Nullable String value) { + if (attributes == null && value != null) { + attributes = new LinkedHashMap<String, String>(); + } + if (value != null) { + attributes.put(key, value); + } else if (attributes != null) { + attributes.remove(key); + } + return this; + } + + public String severity() { + return severity; + } + + public String comment() { + return comment; + } + + public Boolean manualSeverity() { + return manualSeverity; + } + + public String message() { + return message; + } + + public Integer line() { + return line; + } + + public Double cost() { + return cost; + } + + public String resolution() { + return resolution; + } + + public String assigneeLogin() { + return assigneeLogin; + } + + public Map<String, String> attributes() { + return attributes == null ? Collections.<String, String>emptyMap() : new LinkedHashMap<String, String>(attributes); + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQuery.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQuery.java index ab6ec98a9cd..9ab187dab22 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQuery.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQuery.java @@ -22,9 +22,10 @@ package org.sonar.api.issue; import com.google.common.base.Preconditions; import org.apache.commons.lang.builder.ReflectionToStringBuilder; +import org.sonar.api.rule.RuleKey; import java.util.Date; -import java.util.List; +import java.util.Collection; /** * TODO add javadoc @@ -33,16 +34,15 @@ import java.util.List; */ public class IssueQuery { - private final List<String> keys; - private final List<String> severities; - private final List<String> statuses; - private final List<String> resolutions; - private final List<String> components; - private final List<String> componentRoots; - private final String ruleRepository; - private final String rule; - private final List<String> userLogins; - private final List<String> assigneeLogins; + private final Collection<String> keys; + private final Collection<String> severities; + private final Collection<String> statuses; + private final Collection<String> resolutions; + private final Collection<String> components; + private final Collection<String> componentRoots; + private final Collection<RuleKey> rules; + private final Collection<String> userLogins; + private final Collection<String> assigneeLogins; private final Date createdAfter; private final Date createdBefore; private final int limit, offset; @@ -54,8 +54,7 @@ public class IssueQuery { this.resolutions = builder.resolutions; this.components = builder.components; this.componentRoots = builder.componentRoots; - this.ruleRepository = builder.ruleRepository; - this.rule = builder.rule; + this.rules = builder.rules; this.userLogins = builder.userLogins; this.assigneeLogins = builder.assigneeLogins; this.createdAfter = builder.createdAfter; @@ -64,43 +63,39 @@ public class IssueQuery { this.offset = builder.offset; } - public List<String> keys() { + public Collection<String> keys() { return keys; } - public List<String> severities() { + public Collection<String> severities() { return severities; } - public List<String> statuses() { + public Collection<String> statuses() { return statuses; } - public List<String> resolutions() { + public Collection<String> resolutions() { return resolutions; } - public List<String> components() { + public Collection<String> components() { return components; } - public List<String> componentRoots() { + public Collection<String> componentRoots() { return componentRoots; } - public String ruleRepository() { - return ruleRepository; + public Collection<RuleKey> rules() { + return rules; } - public String rule() { - return rule; - } - - public List<String> userLogins() { + public Collection<String> userLogins() { return userLogins; } - public List<String> assigneeLogins() { + public Collection<String> assigneeLogins() { return assigneeLogins; } @@ -138,16 +133,15 @@ public class IssueQuery { private static final int MAX_LIMIT = 5000; private static final int DEFAULT_OFFSET = 0; - private List<String> keys; - private List<String> severities; - private List<String> statuses; - private List<String> resolutions; - private List<String> components; - private List<String> componentRoots; - private String ruleRepository; - private String rule; - private List<String> userLogins; - private List<String> assigneeLogins; + private Collection<String> keys; + private Collection<String> severities; + private Collection<String> statuses; + private Collection<String> resolutions; + private Collection<String> components; + private Collection<String> componentRoots; + private Collection<RuleKey> rules; + private Collection<String> userLogins; + private Collection<String> assigneeLogins; private Date createdAfter; private Date createdBefore; private int limit = DEFAULT_LIMIT; @@ -156,52 +150,47 @@ public class IssueQuery { private Builder() { } - public Builder keys(List<String> l) { + public Builder keys(Collection<String> l) { this.keys = l; return this; } - public Builder severities(List<String> l) { + public Builder severities(Collection<String> l) { this.severities = l; return this; } - public Builder statuses(List<String> l) { + public Builder statuses(Collection<String> l) { this.statuses = l; return this; } - public Builder resolutions(List<String> l) { + public Builder resolutions(Collection<String> l) { this.resolutions = l; return this; } - public Builder components(List<String> l) { + public Builder components(Collection<String> l) { this.components = l; return this; } - public Builder componentRoots(List<String> l) { + public Builder componentRoots(Collection<String> l) { this.componentRoots = l; return this; } - public Builder ruleRepository(String ruleRepository) { - this.ruleRepository = ruleRepository; - return this; - } - - public Builder rule(String rule) { - this.rule = rule; + public Builder rules(Collection<RuleKey> rules) { + this.rules = rules; return this; } - public Builder userLogins(List<String> l) { + public Builder userLogins(Collection<String> l) { this.userLogins = l; return this; } - public Builder assigneeLogins(List<String> l) { + public Builder assigneeLogins(Collection<String> l) { this.assigneeLogins = l; return this; } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/JRubyIssues.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/JRubyIssues.java index af3a0a0bffc..6ec537a8399 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/JRubyIssues.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/JRubyIssues.java @@ -24,7 +24,7 @@ import org.sonar.api.ServerComponent; import java.util.Map; /** - * Facade for JRuby on Rails extensions. + * Facade for JRuby on Rails extensions to request issues. * <p> * Reference from Ruby code : <code>Api.issues</code> * </p> diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleKey.java b/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleKey.java index 6227d717646..a286b0f5750 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleKey.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleKey.java @@ -20,9 +20,14 @@ package org.sonar.api.rule; import com.google.common.base.Preconditions; +import com.google.common.base.Strings; import java.io.Serializable; +/** + * Key of a rule. Unique among all the rule repositories. + * @since 3.6 + */ public class RuleKey implements Serializable { private final String repository, rule; @@ -31,20 +36,35 @@ public class RuleKey implements Serializable { this.rule = rule; } + /** + * Create a key. Parameters are NOT null. + */ public static RuleKey of(String repository, String rule) { + Preconditions.checkArgument(!Strings.isNullOrEmpty(repository), "Repository must be set"); + Preconditions.checkArgument(!Strings.isNullOrEmpty(rule), "Rule must be set"); return new RuleKey(repository, rule); } + /** + * Create a key from a string representation (see {@link #toString()}. An {@link IllegalArgumentException} is raised + * if the format is not valid. + */ public static RuleKey parse(String s) { String[] split = s.split(":"); Preconditions.checkArgument(split.length == 2, "Bad format of rule key: " + s); return RuleKey.of(split[0], split[1]); } + /** + * Never null + */ public String repository() { return repository; } + /** + * Never null + */ public String rule() { return rule; } @@ -75,7 +95,7 @@ public class RuleKey implements Serializable { } /** - * Do not change this format because it's used by customers of the API (rails, ...) + * Format is "repository:rule", for example "squid:AvoidCycle" */ @Override public String toString() { diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/issue/IssueChangeTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/issue/IssueChangeTest.java new file mode 100644 index 00000000000..bd51b76127a --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/issue/IssueChangeTest.java @@ -0,0 +1,41 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.api.issue; + +import org.junit.Test; + +import static org.fest.assertions.Assertions.assertThat; + +public class IssueChangeTest { + @Test + public void should_not_have_changes_by_default() throws Exception { + IssueChange change = IssueChange.create(); + assertThat(change.hasChanges()).isFalse(); + assertThat(change.severity()).isNull(); + assertThat(change.cost()).isNull(); + assertThat(change.assigneeLogin()).isNull(); + assertThat(change.line()).isNull(); + assertThat(change.comment()).isNull(); + assertThat(change.message()).isNull(); + assertThat(change.resolution()).isNull(); + assertThat(change.manualSeverity()).isNull(); + assertThat(change.attributes()).isEmpty(); + } +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/issue/IssueQueryTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/issue/IssueQueryTest.java index 5b3c4491ee4..324d2d78c3c 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/issue/IssueQueryTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/issue/IssueQueryTest.java @@ -21,6 +21,7 @@ package org.sonar.api.issue; import com.google.common.collect.Lists; import org.junit.Test; +import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; import java.util.Date; @@ -36,27 +37,25 @@ public class IssueQueryTest { .severities(Lists.newArrayList(Severity.BLOCKER)) .statuses(Lists.newArrayList(Issue.STATUS_RESOLVED)) .resolutions(Lists.newArrayList(Issue.RESOLUTION_FALSE_POSITIVE)) - .components(Lists.newArrayList("components")) - .componentRoots(Lists.newArrayList("componentRoots")) - .ruleRepository("ruleRepository") - .rule("rule") - .userLogins(Lists.newArrayList("user")) + .components(Lists.newArrayList("org/struts/Action.java")) + .componentRoots(Lists.newArrayList("org.struts:core")) + .rules(Lists.newArrayList(RuleKey.of("squid", "AvoidCycle"))) + .userLogins(Lists.newArrayList("crunky")) .assigneeLogins(Lists.newArrayList("gargantua")) .createdAfter(new Date()) .createdBefore(new Date()) .limit(125) .offset(33) .build(); - assertThat(query.keys()).containsExactly("ABCDE"); - assertThat(query.severities()).containsExactly(Severity.BLOCKER); - assertThat(query.statuses()).containsExactly(Issue.STATUS_RESOLVED); - assertThat(query.resolutions()).containsExactly(Issue.RESOLUTION_FALSE_POSITIVE); - assertThat(query.components()).containsExactly("components"); - assertThat(query.componentRoots()).containsExactly("componentRoots"); - assertThat(query.userLogins()).containsExactly("user"); - assertThat(query.assigneeLogins()).containsExactly("gargantua"); - assertThat(query.ruleRepository()).isEqualTo("ruleRepository"); - assertThat(query.rule()).isEqualTo("rule"); + assertThat(query.keys()).containsOnly("ABCDE"); + assertThat(query.severities()).containsOnly(Severity.BLOCKER); + assertThat(query.statuses()).containsOnly(Issue.STATUS_RESOLVED); + assertThat(query.resolutions()).containsOnly(Issue.RESOLUTION_FALSE_POSITIVE); + assertThat(query.components()).containsOnly("org/struts/Action.java"); + assertThat(query.componentRoots()).containsOnly("org.struts:core"); + assertThat(query.userLogins()).containsOnly("crunky"); + assertThat(query.assigneeLogins()).containsOnly("gargantua"); + assertThat(query.rules()).containsOnly(RuleKey.of("squid", "AvoidCycle")); assertThat(query.createdAfter()).isNotNull(); assertThat(query.createdBefore()).isNotNull(); assertThat(query.limit()).isEqualTo(125); diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleKeyTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleKeyTest.java index d4411fb860f..aee99313bbc 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleKeyTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleKeyTest.java @@ -33,6 +33,46 @@ public class RuleKeyTest { } @Test + public void repository_must_not_be_null() throws Exception { + try { + RuleKey.of(null, "NullDeref"); + fail(); + } catch (IllegalArgumentException e) { + assertThat(e).hasMessage("Repository must be set"); + } + } + + @Test + public void repository_must_not_be_empty() throws Exception { + try { + RuleKey.of("", "NullDeref"); + fail(); + } catch (IllegalArgumentException e) { + assertThat(e).hasMessage("Repository must be set"); + } + } + + @Test + public void rule_must_not_be_null() throws Exception { + try { + RuleKey.of("squid", null); + fail(); + } catch (IllegalArgumentException e) { + assertThat(e).hasMessage("Rule must be set"); + } + } + + @Test + public void rule_must_not_be_empty() throws Exception { + try { + RuleKey.of("squid", ""); + fail(); + } catch (IllegalArgumentException e) { + assertThat(e).hasMessage("Rule must be set"); + } + } + + @Test public void should_encode_and_decode_string() throws Exception { RuleKey key = RuleKey.of("squid", "NullDeref"); String serialized = key.toString(); |