diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2014-10-01 14:59:09 +0200 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2014-10-02 15:27:36 +0200 |
commit | bd4be93baf327fad6d21faae88ed8929039671dc (patch) | |
tree | e4910ca7933c6f1dd1779cbeb1604446510272a3 /server/sonar-server | |
parent | 22710990afe5162eba741dce85d9452ccda7ec66 (diff) | |
download | sonarqube-bd4be93baf327fad6d21faae88ed8929039671dc.tar.gz sonarqube-bd4be93baf327fad6d21faae88ed8929039671dc.zip |
SONAR-5603 Remove useless select methods using IssueQuery in IssueDao
Diffstat (limited to 'server/sonar-server')
7 files changed, 457 insertions, 16 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java new file mode 100644 index 00000000000..e8935b5e87a --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java @@ -0,0 +1,353 @@ +/* + * 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.issue; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; +import org.apache.commons.lang.builder.ReflectionToStringBuilder; +import org.sonar.api.rule.RuleKey; +import org.sonar.server.search.QueryContext; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Set; + +/** + * @since 3.6 + */ +public class IssueQuery { + + public static final String SORT_BY_CREATION_DATE = "CREATION_DATE"; + public static final String SORT_BY_UPDATE_DATE = "UPDATE_DATE"; + public static final String SORT_BY_CLOSE_DATE = "CLOSE_DATE"; + public static final String SORT_BY_ASSIGNEE = "ASSIGNEE"; + public static final String SORT_BY_SEVERITY = "SEVERITY"; + public static final String SORT_BY_STATUS = "STATUS"; + public static final Set<String> SORTS = ImmutableSet.of(SORT_BY_CREATION_DATE, SORT_BY_UPDATE_DATE, SORT_BY_CLOSE_DATE, SORT_BY_ASSIGNEE, SORT_BY_SEVERITY, SORT_BY_STATUS); + + private final Collection<String> issueKeys; + 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> actionPlans; + private final Collection<String> reporters; + private final Collection<String> assignees; + private final Collection<String> languages; + private final Boolean assigned; + private final Boolean planned; + private final Boolean resolved; + private final Boolean hideRules; + private final Date createdAt; + private final Date createdAfter; + private final Date createdBefore; + private final String sort; + private final Boolean asc; + + private IssueQuery(Builder builder) { + this.issueKeys = defaultCollection(builder.issueKeys); + this.severities = defaultCollection(builder.severities); + this.statuses = defaultCollection(builder.statuses); + this.resolutions = defaultCollection(builder.resolutions); + this.components = defaultCollection(builder.components); + this.componentRoots = defaultCollection(builder.componentRoots); + this.rules = defaultCollection(builder.rules); + this.actionPlans = defaultCollection(builder.actionPlans); + this.reporters = defaultCollection(builder.reporters); + this.assignees = defaultCollection(builder.assignees); + this.languages = defaultCollection(builder.languages); + this.assigned = builder.assigned; + this.planned = builder.planned; + this.resolved = builder.resolved; + this.hideRules = builder.hideRules; + this.createdAt = builder.createdAt; + this.createdAfter = builder.createdAfter; + this.createdBefore = builder.createdBefore; + this.sort = builder.sort; + this.asc = builder.asc; + } + + public Collection<String> issueKeys() { + return issueKeys; + } + + public Collection<String> severities() { + return severities; + } + + public Collection<String> statuses() { + return statuses; + } + + public Collection<String> resolutions() { + return resolutions; + } + + public Collection<String> components() { + return components; + } + + public Collection<String> componentRoots() { + return componentRoots; + } + + public Collection<RuleKey> rules() { + return rules; + } + + public Collection<String> actionPlans() { + return actionPlans; + } + + public Collection<String> reporters() { + return reporters; + } + + public Collection<String> assignees() { + return assignees; + } + + public Collection<String> languages() { + return languages; + } + + @CheckForNull + public Boolean assigned() { + return assigned; + } + + @CheckForNull + public Boolean planned() { + return planned; + } + + @CheckForNull + public Boolean resolved() { + return resolved; + } + + /** + * @since 4.2 + */ + @CheckForNull + public Boolean hideRules() { + return hideRules; + } + + @CheckForNull + public Date createdAfter() { + return createdAfter == null ? null : new Date(createdAfter.getTime()); + } + + @CheckForNull + public Date createdAt() { + return createdAt == null ? null : new Date(createdAt.getTime()); + } + + @CheckForNull + public Date createdBefore() { + return createdBefore == null ? null : new Date(createdBefore.getTime()); + } + + @CheckForNull + public String sort() { + return sort; + } + + @CheckForNull + public Boolean asc() { + return asc; + } + + @Override + public String toString() { + return ReflectionToStringBuilder.toString(this); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private Collection<String> issueKeys; + 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> actionPlans; + private Collection<String> reporters; + private Collection<String> assignees; + private Collection<String> languages; + private Boolean assigned = null; + private Boolean planned = null; + private Boolean resolved = null; + private Boolean hideRules = false; + private Date createdAt; + private Date createdAfter; + private Date createdBefore; + private String sort; + private Boolean asc = false; + + private Builder() { + } + + public Builder issueKeys(@Nullable Collection<String> l) { + this.issueKeys = l; + return this; + } + + public Builder severities(@Nullable Collection<String> l) { + this.severities = l; + return this; + } + + public Builder statuses(@Nullable Collection<String> l) { + this.statuses = l; + return this; + } + + public Builder resolutions(@Nullable Collection<String> l) { + this.resolutions = l; + return this; + } + + public Builder components(@Nullable Collection<String> l) { + this.components = l; + return this; + } + + public Builder componentRoots(@Nullable Collection<String> l) { + this.componentRoots = l; + return this; + } + + public Builder rules(@Nullable Collection<RuleKey> rules) { + this.rules = rules; + return this; + } + + public Builder actionPlans(@Nullable Collection<String> l) { + this.actionPlans = l; + return this; + } + + public Builder reporters(@Nullable Collection<String> l) { + this.reporters = l; + return this; + } + + public Builder assignees(@Nullable Collection<String> l) { + this.assignees = l; + return this; + } + + public Builder languages(@Nullable Collection<String> l) { + this.languages = l; + return this; + } + + /** + * If true, it will return all issues assigned to someone + * If false, it will return all issues not assigned to someone + */ + public Builder assigned(@Nullable Boolean b) { + this.assigned = b; + return this; + } + + /** + * If true, it will return all issues linked to an action plan + * If false, it will return all issues not linked to an action plan + */ + public Builder planned(@Nullable Boolean planned) { + this.planned = planned; + return this; + } + + /** + * If true, it will return all resolved issues + * If false, it will return all none resolved issues + */ + public Builder resolved(@Nullable Boolean resolved) { + this.resolved = resolved; + return this; + } + + /** + * If true, rules will not be loaded + * If false, rules will be loaded + * + * @since 4.2 + * + */ + public Builder hideRules(@Nullable Boolean b) { + this.hideRules = b; + return this; + } + + public Builder createdAt(@Nullable Date d) { + this.createdAt = d == null ? null : new Date(d.getTime()); + return this; + } + + public Builder createdAfter(@Nullable Date d) { + this.createdAfter = d == null ? null : new Date(d.getTime()); + return this; + } + + public Builder createdBefore(@Nullable Date d) { + this.createdBefore = d == null ? null : new Date(d.getTime()); + return this; + } + + public Builder sort(@Nullable String s) { + if (s != null && !SORTS.contains(s)) { + throw new IllegalArgumentException("Bad sort field: " + s); + } + this.sort = s; + return this; + } + + public Builder asc(@Nullable Boolean asc) { + this.asc = asc; + return this; + } + + public IssueQuery build() { + if (issueKeys != null) { + Preconditions.checkArgument(issueKeys.size() <= QueryContext.MAX_LIMIT, "Number of issue keys must be less than " + QueryContext.MAX_LIMIT + " (got " + issueKeys.size() + ")"); + } + return new IssueQuery(this); + } + + } + + private static <T> Collection<T> defaultCollection(@Nullable Collection<T> c) { + return c == null ? Collections.<T>emptyList() : Collections.unmodifiableCollection(c); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/actionplan/ActionPlanService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/actionplan/ActionPlanService.java index e25c14ea3c5..3b4e2d72ccc 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/actionplan/ActionPlanService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/actionplan/ActionPlanService.java @@ -32,16 +32,20 @@ import org.sonar.core.issue.ActionPlanStats; import org.sonar.core.issue.DefaultActionPlan; import org.sonar.core.issue.IssueUpdater; import org.sonar.core.issue.db.*; +import org.sonar.core.persistence.DbSession; import org.sonar.core.resource.ResourceDao; import org.sonar.core.resource.ResourceDto; import org.sonar.core.resource.ResourceQuery; +import org.sonar.server.db.DbClient; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.issue.IssueQuery; import org.sonar.server.user.UserSession; import javax.annotation.CheckForNull; -import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.List; import static com.google.common.collect.Lists.newArrayList; @@ -50,19 +54,20 @@ import static com.google.common.collect.Lists.newArrayList; */ public class ActionPlanService implements ServerComponent { + private final DbClient dbClient; + private final ActionPlanDao actionPlanDao; private final ActionPlanStatsDao actionPlanStatsDao; private final ResourceDao resourceDao; - private final IssueDao issueDao; private final IssueUpdater issueUpdater; private final IssueStorage issueStorage; - public ActionPlanService(ActionPlanDao actionPlanDao, ActionPlanStatsDao actionPlanStatsDao, ResourceDao resourceDao, - IssueDao issueDao, IssueUpdater issueUpdater, IssueStorage issueStorage) { + public ActionPlanService(DbClient dbClient, ActionPlanDao actionPlanDao, ActionPlanStatsDao actionPlanStatsDao, ResourceDao resourceDao, + IssueUpdater issueUpdater, IssueStorage issueStorage) { + this.dbClient = dbClient; this.actionPlanDao = actionPlanDao; this.actionPlanStatsDao = actionPlanStatsDao; this.resourceDao = resourceDao; - this.issueDao = issueDao; this.issueUpdater = issueUpdater; this.issueStorage = issueStorage; } @@ -92,10 +97,7 @@ public class ActionPlanService implements ServerComponent { * Unplan all issues linked to an action plan */ private void unplanIssues(DefaultActionPlan actionPlan, UserSession userSession) { - // Get all issues linked to this plan (need to disable pagination and authorization check) - IssueQuery query = IssueQuery.builder().actionPlans(Arrays.asList(actionPlan.key())).requiredRole(null).build(); - // TODO use IssueService - List<IssueDto> dtos = issueDao.selectIssues(query); + List<IssueDto> dtos = findIssuesByActionPlan(actionPlan.key()); IssueChangeContext context = IssueChangeContext.createUser(new Date(), userSession.login()); List<DefaultIssue> issues = newArrayList(); for (IssueDto issueDto : dtos) { @@ -109,6 +111,15 @@ public class ActionPlanService implements ServerComponent { issueStorage.save(issues); } + private List<IssueDto> findIssuesByActionPlan(String actionPlanKey){ + DbSession session = dbClient.openSession(false); + try { + return dbClient.issueDao().findByActionPlan(session, actionPlanKey); + } finally { + session.close(); + } + } + public ActionPlan setStatus(String actionPlanKey, String status, UserSession userSession) { ActionPlanDto actionPlanDto = findActionPlanDto(actionPlanKey); checkUserIsProjectAdministrator(actionPlanDto.getProjectKey(), userSession); diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java b/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java index 7331bfe9eb2..df3dec2284c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java @@ -56,6 +56,10 @@ public class IssueDao extends BaseDao<IssueMapper, IssueDto, String> implements return mapper(session).selectByKeys(keys); } + public List<IssueDto> findByActionPlan(DbSession session, String actionPlan) { + return mapper(session).selectByActionPlan(actionPlan); + } + @Override protected IssueDto doUpdate(DbSession session, IssueDto issue) { mapper(session).update(issue); diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java index 4e7cb0f9c62..c808234d7a5 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java @@ -40,7 +40,6 @@ import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.Duration; import org.sonar.api.utils.Durations; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; import org.sonar.core.component.ComponentDto; import org.sonar.core.issue.db.IssueChangeDao; import org.sonar.core.persistence.DbSession; @@ -190,7 +189,6 @@ public class SearchAction extends SearchRequestHandler<IssueQuery, Issue> { @Override protected IssueQuery doQuery(Request request) { IssueQuery.Builder builder = IssueQuery.builder() - .requiredRole(UserRole.USER) .issueKeys(request.paramAsStrings(IssueFilterParameters.ISSUES)) .severities(request.paramAsStrings(IssueFilterParameters.SEVERITIES)) .statuses(request.paramAsStrings(IssueFilterParameters.STATUSES)) diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/actionplan/ActionPlanServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/actionplan/ActionPlanServiceTest.java index 85b13f5be44..4dc67fe4c8e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/actionplan/ActionPlanServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/actionplan/ActionPlanServiceTest.java @@ -36,12 +36,13 @@ import org.sonar.core.issue.ActionPlanStats; import org.sonar.core.issue.DefaultActionPlan; import org.sonar.core.issue.IssueUpdater; import org.sonar.core.issue.db.*; +import org.sonar.core.persistence.DbSession; import org.sonar.core.resource.ResourceDao; import org.sonar.core.resource.ResourceDto; import org.sonar.core.resource.ResourceQuery; +import org.sonar.server.db.DbClient; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.issue.IssueQuery; import org.sonar.server.user.MockUserSession; import org.sonar.server.user.UserSession; @@ -57,6 +58,12 @@ import static org.mockito.Mockito.*; public class ActionPlanServiceTest { @Mock + DbClient dbClient; + + @Mock + DbSession session; + + @Mock ActionPlanDao actionPlanDao; @Mock @@ -66,7 +73,7 @@ public class ActionPlanServiceTest { ResourceDao resourceDao; @Mock - IssueDao issueDao; + org.sonar.server.issue.db.IssueDao issueDao; @Mock IssueUpdater issueUpdater; @@ -84,7 +91,9 @@ public class ActionPlanServiceTest { @Before public void before() { - actionPlanService = new ActionPlanService(actionPlanDao, actionPlanStatsDao, resourceDao, issueDao, issueUpdater, issueStorage); + when(dbClient.openSession(false)).thenReturn(session); + when(dbClient.issueDao()).thenReturn(issueDao); + actionPlanService = new ActionPlanService(dbClient, actionPlanDao, actionPlanStatsDao, resourceDao, issueUpdater, issueStorage); } @Test @@ -145,7 +154,7 @@ public class ActionPlanServiceTest { when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l)); IssueDto issueDto = new IssueDto().setId(100L).setStatus(Issue.STATUS_OPEN).setRuleKey("squid", "s100"); - when(issueDao.selectIssues(any(IssueQuery.class))).thenReturn(newArrayList(issueDto)); + when(issueDao.findByActionPlan(session, "ABCD")).thenReturn(newArrayList(issueDto)); when(issueUpdater.plan(any(DefaultIssue.class), eq((ActionPlan) null), any(IssueChangeContext.class))).thenReturn(true); ArgumentCaptor<DefaultIssue> captor = ArgumentCaptor.forClass(DefaultIssue.class); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java index 7a4846e12cd..074fa458a1d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java @@ -129,6 +129,43 @@ public class IssueDaoTest extends AbstractDaoTestCase { } @Test + public void find_by_action_plan() { + setupData("shared", "find_by_action_plan"); + + List<IssueDto> issues = dao.findByActionPlan(session, "AP-1"); + assertThat(issues).hasSize(1); + + IssueDto issue = issues.get(0); + assertThat(issue.getKee()).isEqualTo("ABCDE"); + assertThat(issue.getActionPlanKey()).isEqualTo("AP-1"); + assertThat(issue.getComponentId()).isEqualTo(401); + assertThat(issue.getRootComponentId()).isEqualTo(399); + assertThat(issue.getRuleId()).isEqualTo(500); + assertThat(issue.getLanguage()).isEqualTo("java"); + assertThat(issue.getSeverity()).isEqualTo("BLOCKER"); + assertThat(issue.isManualSeverity()).isFalse(); + assertThat(issue.getMessage()).isNull(); + assertThat(issue.getLine()).isEqualTo(200); + assertThat(issue.getEffortToFix()).isEqualTo(4.2); + assertThat(issue.getStatus()).isEqualTo("OPEN"); + assertThat(issue.getResolution()).isEqualTo("FIXED"); + assertThat(issue.getChecksum()).isEqualTo("XXX"); + assertThat(issue.getAuthorLogin()).isEqualTo("karadoc"); + assertThat(issue.getReporter()).isEqualTo("arthur"); + assertThat(issue.getAssignee()).isEqualTo("perceval"); + assertThat(issue.getIssueAttributes()).isEqualTo("JIRA=FOO-1234"); + assertThat(issue.getIssueCreationDate()).isNotNull(); + assertThat(issue.getIssueUpdateDate()).isNotNull(); + assertThat(issue.getIssueCloseDate()).isNotNull(); + assertThat(issue.getCreatedAt()).isNotNull(); + assertThat(issue.getUpdatedAt()).isNotNull(); + assertThat(issue.getRuleRepo()).isEqualTo("squid"); + assertThat(issue.getRule()).isEqualTo("AvoidCycle"); + assertThat(issue.getComponentKey()).isEqualTo("Action.java"); + assertThat(issue.getRootComponentKey()).isEqualTo("struts"); + } + + @Test public void find_after_dates() throws Exception { setupData("shared", "some_issues"); diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/find_by_action_plan.xml b/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/find_by_action_plan.xml new file mode 100644 index 00000000000..6ba7716170a --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/find_by_action_plan.xml @@ -0,0 +1,29 @@ +<dataset> + + <issues + id="100" + kee="ABCDE" + component_id="401" + root_component_id="399" + rule_id="500" + severity="BLOCKER" + manual_severity="[false]" + message="[null]" + line="200" + effort_to_fix="4.2" + status="OPEN" + resolution="FIXED" + checksum="XXX" + reporter="arthur" + assignee="perceval" + action_plan_key="AP-1" + author_login="karadoc" + issue_attributes="JIRA=FOO-1234" + issue_creation_date="2013-04-16" + issue_update_date="2013-04-16" + issue_close_date="2013-04-16" + created_at="2013-04-16" + updated_at="2013-04-16" + /> + +</dataset> |