From d6859617c1badd3dbfeed0aa9fc771dc35f7b08f Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Wed, 5 Jun 2013 18:37:00 +0200 Subject: [PATCH] SONAR-3755 improve documentation --- .../core/issue/DefaultIssueQueryResult.java | 2 +- .../issue/DefaultIssueQueryResultTest.java | 4 +-- .../main/java/org/sonar/api/issue/Issue.java | 21 +++++++++++++++- .../org/sonar/api/issue/IssueQueryResult.java | 25 ++++++++++++++++--- .../org/sonar/api/issue/RubyIssueService.java | 8 +++--- .../org/sonar/api/issue/action/Action.java | 8 +++--- .../org/sonar/api/issue/action/Actions.java | 3 +++ .../condition/HasIssuePropertyCondition.java | 4 +-- .../api/issue/internal/DefaultIssue.java | 15 +++++++---- .../issue/internal/DefaultIssueComment.java | 2 ++ .../sonar/api/issue/internal/FieldDiffs.java | 2 ++ .../issue/internal/IssueChangeContext.java | 8 +++--- .../api/issue/internal/DefaultIssueTest.java | 20 +++++++++++++++ .../sonar/server/issue/ActionServiceTest.java | 18 ++++++------- 14 files changed, 105 insertions(+), 35 deletions(-) diff --git a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueQueryResult.java b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueQueryResult.java index 2e6a8245dc1..ca92f7e8d29 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueQueryResult.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueQueryResult.java @@ -107,7 +107,7 @@ public class DefaultIssueQueryResult implements IssueQueryResult { if (issues != null && !issues.isEmpty()) { return issues.get(0); } - throw new IllegalArgumentException("No issue"); + throw new IllegalStateException("No issue"); } @Override diff --git a/sonar-core/src/test/java/org/sonar/core/issue/DefaultIssueQueryResultTest.java b/sonar-core/src/test/java/org/sonar/core/issue/DefaultIssueQueryResultTest.java index 7f442ea19a7..9148e9ccf85 100644 --- a/sonar-core/src/test/java/org/sonar/core/issue/DefaultIssueQueryResultTest.java +++ b/sonar-core/src/test/java/org/sonar/core/issue/DefaultIssueQueryResultTest.java @@ -31,8 +31,8 @@ import static org.fest.assertions.Assertions.assertThat; public class DefaultIssueQueryResultTest { - @Test(expected = IllegalArgumentException.class) - public void should_first_throw_exception_if_no_issue() { + @Test(expected = IllegalStateException.class) + public void first_should_throw_exception_if_no_issues() { DefaultIssueQueryResult result = new DefaultIssueQueryResult(Collections.emptyList()); result.first(); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java index 982ed14ff94..77d92abed4f 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java @@ -83,6 +83,9 @@ public interface Issue extends Serializable { @CheckForNull String message(); + /** + * Optional line number. If set, then it's greater than or equal 1. + */ @CheckForNull Integer line(); @@ -99,17 +102,26 @@ public interface Issue extends Serializable { @CheckForNull Double effortToFix(); + /** + * See constant values in {@link Issue}. + */ String status(); /** - * The type of resolution, or null if the issue is not resolved. + * The type of resolution, or null if the issue is not resolved. See constant values in {@link Issue}. */ @CheckForNull String resolution(); + /** + * Login of the user who reported this issue. Null if the issue is reported by a rule engine. + */ @CheckForNull String reporter(); + /** + * Login of the user who is assigned to this issue. Null if the issue is not assigned. + */ @CheckForNull String assignee(); @@ -117,6 +129,9 @@ public interface Issue extends Serializable { Date updateDate(); + /** + * Date when status was set to {@link Issue#STATUS_CLOSED}, else null. + */ @CheckForNull Date closeDate(); @@ -125,6 +140,10 @@ public interface Issue extends Serializable { Map attributes(); + /** + * Login of the SCM account that introduced this issue. Requires the + * Developer Cockpit Plugin to be installed. + */ @CheckForNull String authorLogin(); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQueryResult.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQueryResult.java index 4caa572140a..6dedb9e5ab7 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQueryResult.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQueryResult.java @@ -33,14 +33,20 @@ import java.util.List; * @since 3.6 */ public interface IssueQueryResult { + /** + * Non-null paginated list of issues. + */ List issues(); /** - * Return first issue in the list. - * It will throws IllegalArgumentException if no issue found. + * Returns the first issue in the list. + * @throws IllegalStateException if the list is empty. */ Issue first(); + /** + * Returns the rule associated to the given issue. + */ Rule rule(Issue issue); /** @@ -62,22 +68,33 @@ public interface IssueQueryResult { */ Collection projects(); - @CheckForNull ActionPlan actionPlan(Issue issue); + /** + * The action plans involved in the paginated {@link #issues()}. + */ Collection actionPlans(); /** - * The users involved in the paginated {@link #issues()}, for example people who added a comment, created an issue + * The users involved in the paginated {@link #issues()}, for example people who added a comment, reported an issue * or are assigned to issues. */ Collection users(); + /** + * Returns the user with the given login. Users that are not returned by {@link #users()} are ignored. + */ @CheckForNull User user(String login); + /** + * Non-null data about paging of issues + */ Paging paging(); + /** + * True if too many issues have been found. In this case results are truncated. + */ boolean maxResultsReached(); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/RubyIssueService.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/RubyIssueService.java index 7956b5e17f0..440105e5787 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/RubyIssueService.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/RubyIssueService.java @@ -36,17 +36,17 @@ public interface RubyIssueService extends ServerComponent { /** * Search for an issue by its key. *

- * Ruby example: {@code Api.issues.find('ABCDE-12345')} + * Ruby example: result = Api.issues.find('ABCDE-12345') */ IssueQueryResult find(String issueKey); /** * Search for issues. *

- * Ruby example: {@code Api.issues.find({'statuses' => ['OPEN', 'RESOLVED'], 'assignees' => 'john,carla')}. + * Ruby example: Api.issues.find({'statuses' => ['OPEN', 'RESOLVED'], 'assignees' => 'john,carla')} *

- * Keys of parameters must be Ruby strings but not symbols. Multi-value parameters can be arrays ({@code ['OPEN', 'RESOLVED']}) or - * comma-separated list of strings ({@code 'OPEN,RESOLVED'}). + * Keys of parameters must be Ruby strings but not symbols. Multi-value parameters can be arrays (['OPEN', 'RESOLVED']) or + * comma-separated list of strings ('OPEN,RESOLVED'). *

* Optional parameters are: *

    diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/action/Action.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/action/Action.java index a797d20106c..3f1c50fc3b0 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/action/Action.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/action/Action.java @@ -29,18 +29,20 @@ import java.util.List; import static com.google.common.collect.Lists.newArrayList; +/** + * @since 3.6 + */ public class Action { private final String key; private final List conditions; private final List functions; - public Action(String key) { + Action(String key) { + Preconditions.checkArgument(!Strings.isNullOrEmpty(key), "Action key must be set"); this.key = key; this.conditions = newArrayList(); this.functions = newArrayList(); - - Preconditions.checkArgument(!Strings.isNullOrEmpty(key), "Action key must be set"); } public String key() { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/action/Actions.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/action/Actions.java index ae6ccb0e2cb..58522414816 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/action/Actions.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/action/Actions.java @@ -25,6 +25,9 @@ import java.util.List; import static com.google.common.collect.Lists.newArrayList; +/** + * @since 3.6 + */ public class Actions implements ServerExtension { private final List actions; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/condition/HasIssuePropertyCondition.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/condition/HasIssuePropertyCondition.java index d6386e9ed8b..cb99f21d8e3 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/condition/HasIssuePropertyCondition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/condition/HasIssuePropertyCondition.java @@ -19,15 +19,13 @@ */ package org.sonar.api.issue.condition; -import com.google.common.annotations.Beta; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import org.sonar.api.issue.Issue; /** - * @since 3.1 + * @since 3.6 */ -@Beta public final class HasIssuePropertyCondition implements Condition { private final String propertyKey; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssue.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssue.java index 5ba60e544d1..0a4ba0394e8 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssue.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssue.java @@ -22,6 +22,7 @@ package org.sonar.api.issue.internal; import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -35,7 +36,6 @@ import org.sonar.api.rule.Severity; import javax.annotation.CheckForNull; import javax.annotation.Nullable; - import java.io.Serializable; import java.util.Collections; import java.util.Date; @@ -43,6 +43,8 @@ import java.util.List; import java.util.Map; /** + * PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING. + * * @since 3.6 */ public class DefaultIssue implements Issue { @@ -275,9 +277,9 @@ public class DefaultIssue implements Issue { /** * True when one of the following conditions is true : *
      - *
    • the related component has been deleted or renamed
    • - *
    • the rule has been deleted (eg. on plugin uninstall)
    • - *
    • the rule has been disabled in the Quality profile
    • + *
    • the related component has been deleted or renamed
    • + *
    • the rule has been deleted (eg. on plugin uninstall)
    • + *
    • the rule has been disabled in the Quality profile
    • *
    */ public boolean isEndOfLife() { @@ -384,7 +386,10 @@ public class DefaultIssue implements Issue { @SuppressWarnings("unchcked") public List comments() { - return Objects.firstNonNull(comments, Collections.emptyList()); + if (comments == null) { + return Collections.emptyList(); + } + return ImmutableList.copyOf(comments); } @CheckForNull diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssueComment.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssueComment.java index 318b6c7117e..2418943cc3d 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssueComment.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssueComment.java @@ -29,6 +29,8 @@ import java.util.Date; import java.util.UUID; /** + * PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING. + * * @since 3.6 */ public class DefaultIssueComment implements Serializable, IssueComment { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/FieldDiffs.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/FieldDiffs.java index b0d44ee6bf9..9d954cbd77a 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/FieldDiffs.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/FieldDiffs.java @@ -30,6 +30,8 @@ import java.util.Date; import java.util.Map; /** + * PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING. + * * @since 3.6 */ public class FieldDiffs implements Serializable { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/IssueChangeContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/IssueChangeContext.java index 1e462235a96..e8a0b6cef3a 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/IssueChangeContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/IssueChangeContext.java @@ -26,13 +26,15 @@ import java.io.Serializable; import java.util.Date; /** + * PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING. + * * @since 3.6 */ public class IssueChangeContext implements Serializable { - private String login; - private Date date; - private boolean scan; + private final String login; + private final Date date; + private final boolean scan; private IssueChangeContext(@Nullable String login, Date date, boolean scan) { this.login = login; diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/issue/internal/DefaultIssueTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/issue/internal/DefaultIssueTest.java index 247e60d41d2..b50e7f32594 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/issue/internal/DefaultIssueTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/issue/internal/DefaultIssueTest.java @@ -22,6 +22,9 @@ package org.sonar.api.issue.internal; import com.google.common.collect.ImmutableMap; import org.apache.commons.lang.StringUtils; import org.junit.Test; +import org.sonar.api.issue.IssueComment; + +import java.util.List; import static org.fest.assertions.Assertions.assertThat; import static org.fest.assertions.Fail.fail; @@ -112,4 +115,21 @@ public class DefaultIssueTest { assertThat(a1).isNotEqualTo(b); assertThat(a1.hashCode()).isEqualTo(a1.hashCode()); } + + @Test + public void comments_should_not_be_modifiable() throws Exception { + DefaultIssue issue = new DefaultIssue().setKey("AAA"); + + List comments = issue.comments(); + assertThat(comments).isEmpty(); + + try { + comments.add(new DefaultIssueComment()); + fail(); + } catch (UnsupportedOperationException e) { + // ok + } catch (Exception e) { + fail("Unexpected exception: " + e); + } + } } diff --git a/sonar-server/src/test/java/org/sonar/server/issue/ActionServiceTest.java b/sonar-server/src/test/java/org/sonar/server/issue/ActionServiceTest.java index 38838e17833..1e4831301ad 100644 --- a/sonar-server/src/test/java/org/sonar/server/issue/ActionServiceTest.java +++ b/sonar-server/src/test/java/org/sonar/server/issue/ActionServiceTest.java @@ -49,13 +49,13 @@ import static org.mockito.Mockito.*; public class ActionServiceTest { - private DefaultIssueFinder finder; - private IssueStorage issueStorage; - private IssueUpdater updater; - private PropertiesDao propertiesDao; - private Settings settings; - private Actions actions; - private ActionService actionService; + DefaultIssueFinder finder; + IssueStorage issueStorage; + IssueUpdater updater; + PropertiesDao propertiesDao; + Settings settings; + Actions actions; + ActionService actionService; @Before public void before() { @@ -124,7 +124,7 @@ public class ActionServiceTest { actionService.execute("ABCD", "link-to-jira", mock(UserSession.class)); fail(); } catch (Exception e) { - assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("No issue"); + assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("No issue"); } verifyZeroInteractions(function); } @@ -187,7 +187,7 @@ public class ActionServiceTest { actionService.listAvailableActions("ABCD"); fail(); } catch (Exception e) { - assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("No issue"); + assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("No issue"); } } -- 2.39.5