aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java235
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java14
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/IssueBulkChangeService.java31
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/IssueChangelogService.java20
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java32
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/PublicRubyIssueService.java134
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterResult.java46
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java341
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceTest.java31
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/IssueChangelogServiceTest.java30
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/PublicRubyIssueServiceTest.java132
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/models/api.rb6
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/models/internal.rb4
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueQueryResult.java175
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/IssueNotifications.java23
-rw-r--r--sonar-core/src/test/java/org/sonar/core/issue/DefaultIssueQueryResultTest.java50
-rw-r--r--sonar-core/src/test/java/org/sonar/core/issue/IssueNotificationsTest.java28
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueFinder.java34
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQueryResult.java108
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/issue/RubyIssueService.java81
22 files changed, 80 insertions, 1480 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java b/server/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java
deleted file mode 100644
index 0c72c7c8bef..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * 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.Function;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.component.Component;
-import org.sonar.api.issue.*;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.user.User;
-import org.sonar.api.user.UserFinder;
-import org.sonar.api.utils.Paging;
-import org.sonar.core.component.ComponentDto;
-import org.sonar.core.issue.DefaultIssueQueryResult;
-import org.sonar.core.issue.db.IssueChangeDao;
-import org.sonar.core.issue.db.IssueDao;
-import org.sonar.core.issue.db.IssueDto;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.server.issue.actionplan.ActionPlanService;
-import org.sonar.server.rule.DefaultRuleFinder;
-import org.sonar.server.user.UserSession;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-import java.util.*;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.Maps.newHashMap;
-import static com.google.common.collect.Sets.newHashSet;
-
-/**
- * @since 3.6
- */
-public class DefaultIssueFinder implements IssueFinder {
-
- private static final Logger LOG = LoggerFactory.getLogger(DefaultIssueFinder.class);
- private final MyBatis myBatis;
- private final IssueDao issueDao;
- private final IssueChangeDao issueChangeDao;
- private final DefaultRuleFinder ruleFinder;
- private final UserFinder userFinder;
- private final ResourceDao resourceDao;
- private final ActionPlanService actionPlanService;
-
- public DefaultIssueFinder(MyBatis myBatis,
- IssueDao issueDao, IssueChangeDao issueChangeDao,
- DefaultRuleFinder ruleFinder,
- UserFinder userFinder,
- ResourceDao resourceDao,
- ActionPlanService actionPlanService) {
- this.myBatis = myBatis;
- this.issueDao = issueDao;
- this.issueChangeDao = issueChangeDao;
- this.ruleFinder = ruleFinder;
- this.userFinder = userFinder;
- this.resourceDao = resourceDao;
- this.actionPlanService = actionPlanService;
- }
-
- DefaultIssue findByKey(String issueKey, String requiredRole) {
- IssueDto dto = issueDao.selectByKey(issueKey);
- if (dto == null) {
- throw new IllegalStateException("Unknown issue: " + issueKey);
- }
- if (!UserSession.get().hasProjectPermission(requiredRole, dto.getRootComponentKey())) {
- throw new IllegalStateException("User does not have the required role required to change the issue: " + issueKey);
- }
-
- return dto.toDefaultIssue();
- }
-
- @Override
- public IssueQueryResult find(IssueQuery query) {
- LOG.debug("IssueQuery : {}", query);
- long start = System.currentTimeMillis();
- DbSession sqlSession = myBatis.openSession(false);
- try {
- // 1. Select the authorized ids of all the issues that match the query
- List<IssueDto> authorizedIssues = issueDao.selectIssueIds(query, UserSession.get().userId(), sqlSession);
-
- // 2. Sort all authorized issues
- List<IssueDto> authorizedSortedIssues = sort(authorizedIssues, query, authorizedIssues.size());
-
- // 3. Apply pagination
- Paging paging = Paging.create(query.pageSize(), query.pageIndex(), authorizedSortedIssues.size());
- Set<Long> pagedIssueIds = pagedIssueIds(authorizedSortedIssues, paging);
-
- // 4. Load issues and their related data (rules, components, projects, comments, action plans, ...) and sort then again
- List<IssueDto> pagedIssues = issueDao.selectByIds(pagedIssueIds, sqlSession);
- List<IssueDto> pagedSortedIssues = sort(pagedIssues, query, authorizedIssues.size());
-
- Map<String, DefaultIssue> issuesByKey = newHashMap();
- List<Issue> issues = newArrayList();
- Set<Integer> ruleIds = newHashSet();
- Set<Long> componentIds = newHashSet();
- Set<String> actionPlanKeys = newHashSet();
- Set<String> users = newHashSet();
- for (IssueDto dto : pagedSortedIssues) {
- DefaultIssue defaultIssue = dto.toDefaultIssue();
- issuesByKey.put(dto.getKee(), defaultIssue);
- issues.add(defaultIssue);
- ruleIds.add(dto.getRuleId());
- componentIds.add(dto.getComponentId());
- actionPlanKeys.add(dto.getActionPlanKey());
- if (dto.getReporter() != null) {
- users.add(dto.getReporter());
- }
- if (dto.getAssignee() != null) {
- users.add(dto.getAssignee());
- }
- }
- List<DefaultIssueComment> comments = issueChangeDao.selectCommentsByIssues(sqlSession, issuesByKey.keySet());
- for (DefaultIssueComment comment : comments) {
- DefaultIssue issue = issuesByKey.get(comment.issueKey());
- issue.addComment(comment);
- if (comment.userLogin() != null) {
- users.add(comment.userLogin());
- }
- }
-
- Collection<Component> components = findComponents(componentIds);
- Collection<Component> groupComponents = findSubProjects(components);
- Collection<Component> rootComponents = findProjects(components);
-
- Set<Component> allComponents = newHashSet(components);
- allComponents.addAll(groupComponents);
- allComponents.addAll(rootComponents);
-
- return new DefaultIssueQueryResult(issues)
- .setMaxResultsReached(authorizedIssues.size() == query.maxResults())
- .addRules(hideRules(query) ? Collections.<Rule>emptyList() : findRules(ruleIds))
- .addComponents(allComponents)
- .addProjects(rootComponents)
- .addActionPlans(findActionPlans(actionPlanKeys))
- .addUsers(findUsers(users))
- .setPaging(paging);
- } finally {
- MyBatis.closeQuietly(sqlSession);
- LOG.debug("IssueQuery execution time : {} ms", System.currentTimeMillis() - start);
- }
- }
-
- private boolean hideRules(IssueQuery query) {
- Boolean hideRules = query.hideRules();
- return hideRules != null ? hideRules : false;
- }
-
- private List<IssueDto> sort(List<IssueDto> issues, IssueQuery query, int allIssuesSize) {
- if (allIssuesSize < query.maxResults()) {
- return new IssuesFinderSort(issues, query).sort();
- }
- return issues;
- }
-
- private Set<Long> pagedIssueIds(Collection<IssueDto> issues, Paging paging) {
- Set<Long> issueIds = Sets.newLinkedHashSet();
- int index = 0;
- for (IssueDto issue : issues) {
- if (index >= paging.offset() && issueIds.size() < paging.pageSize()) {
- issueIds.add(issue.getId());
- } else if (issueIds.size() >= paging.pageSize()) {
- break;
- }
- index++;
- }
- return issueIds;
- }
-
- private Collection<Rule> findRules(Set<Integer> ruleIds) {
- return ruleFinder.findByIds(ruleIds);
- }
-
- private Collection<User> findUsers(Set<String> logins) {
- return userFinder.findByLogins(Lists.newArrayList(logins));
- }
-
- private Collection<Component> findComponents(Set<Long> componentIds) {
- return Lists.<Component>newArrayList(resourceDao.selectComponentsByIds(componentIds));
- }
-
- private Collection<Component> findSubProjects(Collection<Component> components) {
- return findComponents(newHashSet(Iterables.transform(components, new Function<Component, Long>() {
- @Override
- public Long apply(@Nullable Component input) {
- return input != null ? ((ComponentDto) input).subProjectId() : null;
- }
- })));
- }
-
- private Collection<Component> findProjects(Collection<Component> components) {
- return findComponents(newHashSet(Iterables.transform(components, new Function<Component, Long>() {
- @Override
- public Long apply(@Nullable Component input) {
- return input != null ? ((ComponentDto) input).projectId() : null;
- }
- })));
- }
-
- private Collection<ActionPlan> findActionPlans(Set<String> actionPlanKeys) {
- return actionPlanService.findByKeys(actionPlanKeys);
- }
-
- @CheckForNull
- public Issue findByKey(String key) {
- IssueDto dto = issueDao.selectByKey(key);
- return dto != null ? dto.toDefaultIssue() : null;
- }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java
index 35b103a29f5..91c23e4e102 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java
@@ -111,12 +111,12 @@ public class InternalRubyIssueService implements ServerComponent {
this.issueBulkChangeService = issueBulkChangeService;
}
- public Issue getIssueByKey(String issueKey){
+ public Issue getIssueByKey(String issueKey) {
return issueService.getByKey(issueKey);
}
public IssueStatsFinder.IssueStatsResult findIssueAssignees(Map<String, Object> params) {
- return issueStatsFinder.findIssueAssignees(PublicRubyIssueService.toQuery(params));
+ return issueStatsFinder.findIssueAssignees(toQuery(params));
}
public List<Transition> listTransitions(String issueKey) {
@@ -156,11 +156,11 @@ public class InternalRubyIssueService implements ServerComponent {
}));
}
- public List<DefaultIssueComment> findComments(String issueKey){
+ public List<DefaultIssueComment> findComments(String issueKey) {
return commentService.findComments(issueKey);
}
- public List<DefaultIssueComment> findCommentsByIssueKeys(Collection<String> issueKeys){
+ public List<DefaultIssueComment> findCommentsByIssueKeys(Collection<String> issueKeys) {
return commentService.findComments(issueKeys);
}
@@ -429,7 +429,7 @@ public class InternalRubyIssueService implements ServerComponent {
}
public IssueQuery emptyIssueQuery() {
- return PublicRubyIssueService.toQuery(Maps.<String, Object>newHashMap());
+ return toQuery(Maps.<String, Object>newHashMap());
}
@CheckForNull
@@ -635,7 +635,7 @@ public class InternalRubyIssueService implements ServerComponent {
}
}
- public int maxPageSize(){
+ public int maxPageSize() {
return IssueQuery.MAX_PAGE_SIZE;
}
@@ -670,7 +670,7 @@ public class InternalRubyIssueService implements ServerComponent {
}
@VisibleForTesting
- static QueryContext toContext(Map<String, Object> props){
+ static QueryContext toContext(Map<String, Object> props) {
QueryContext context = new QueryContext();
Integer pageIndex = RubyUtils.toInteger(props.get(IssueFilterParameters.PAGE_INDEX));
Integer pageSize = RubyUtils.toInteger(props.get(IssueFilterParameters.PAGE_SIZE));
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueBulkChangeService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueBulkChangeService.java
index 10dc8b4b173..646f825e054 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueBulkChangeService.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueBulkChangeService.java
@@ -20,26 +20,31 @@
package org.sonar.server.issue;
+import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.IssueQuery;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.issue.internal.IssueChangeContext;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.Rule;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.issue.IssueNotifications;
+import org.sonar.core.issue.db.IssueDto;
import org.sonar.core.issue.db.IssueStorage;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.preview.PreviewCache;
import org.sonar.server.db.DbClient;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.rule.DefaultRuleFinder;
+import org.sonar.server.search.QueryContext;
import org.sonar.server.user.UserSession;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import java.util.*;
@@ -77,7 +82,7 @@ public class IssueBulkChangeService {
IssueBulkChangeResult result = new IssueBulkChangeResult();
- List<Issue> issues = issueService.search(issueBulkChangeQuery.issues());
+ List<Issue> issues = getByKeysForUpdate(issueBulkChangeQuery.issues());
Referentials referentials = new Referentials(issues);
List<Action> bulkActions = getActionsToApply(issueBulkChangeQuery, issues, userSession);
@@ -114,6 +119,30 @@ public class IssueBulkChangeService {
return result;
}
+ private List<Issue> getByKeysForUpdate(List<String> issueKeys) {
+ // Load from index to check permission
+ List<Issue> authorizedIndexIssues = issueService.search(IssueQuery.builder().issueKeys(issueKeys).build(), new QueryContext().setMaxLimit()).getHits();
+ List<String> authorizedIssueKeys = newArrayList(Iterables.transform(authorizedIndexIssues, new Function<Issue, String>() {
+ @Override
+ public String apply(@Nullable Issue input) {
+ return input != null ? input.key() : null;
+ }
+ }));
+
+ DbSession session = dbClient.openSession(false);
+ try {
+ List<IssueDto> issueDtos = dbClient.issueDao().getByKeys(session, authorizedIssueKeys);
+ return newArrayList(Iterables.transform(issueDtos, new Function<IssueDto, Issue>() {
+ @Override
+ public Issue apply(@Nullable IssueDto input) {
+ return input != null ? input.toDefaultIssue() : null;
+ }
+ }));
+ } finally {
+ session.close();
+ }
+ }
+
private List<Action> getActionsToApply(IssueBulkChangeQuery issueBulkChangeQuery, List<Issue> issues, UserSession userSession) {
List<Action> bulkActions = newArrayList();
for (String actionKey : issueBulkChangeQuery.actions()) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueChangelogService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueChangelogService.java
index d1390f4f79a..c70f7cf67ca 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueChangelogService.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueChangelogService.java
@@ -21,14 +21,10 @@ package org.sonar.server.issue;
import org.sonar.api.ServerComponent;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueQuery;
-import org.sonar.api.issue.IssueQueryResult;
import org.sonar.api.issue.internal.FieldDiffs;
import org.sonar.api.user.User;
import org.sonar.api.user.UserFinder;
-import org.sonar.api.web.UserRole;
import org.sonar.core.issue.db.IssueChangeDao;
-import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.user.UserSession;
import java.util.Collection;
@@ -43,18 +39,18 @@ public class IssueChangelogService implements ServerComponent {
private final IssueChangeDao changeDao;
private final UserFinder userFinder;
- private final DefaultIssueFinder finder;
+ private final IssueService issueService;
private final IssueChangelogFormatter formatter;
- public IssueChangelogService(IssueChangeDao changeDao, UserFinder userFinder, DefaultIssueFinder finder, IssueChangelogFormatter formatter) {
+ public IssueChangelogService(IssueChangeDao changeDao, UserFinder userFinder, IssueService issueService, IssueChangelogFormatter formatter) {
this.changeDao = changeDao;
this.userFinder = userFinder;
- this.finder = finder;
+ this.issueService = issueService;
this.formatter = formatter;
}
public IssueChangelog changelog(String issueKey) {
- Issue issue = loadIssue(issueKey).first();
+ Issue issue = issueService.getByKey(issueKey);
return changelog(issue);
}
@@ -72,14 +68,6 @@ public class IssueChangelogService implements ServerComponent {
return new IssueChangelog(changes, users);
}
- public IssueQueryResult loadIssue(String issueKey) {
- IssueQueryResult result = finder.find(IssueQuery.builder().issueKeys(newArrayList(issueKey)).requiredRole(UserRole.USER).build());
- if (result.issues().size() != 1) {
- throw new NotFoundException("Issue not found: " + issueKey);
- }
- return result;
- }
-
public List<String> formatDiffs(FieldDiffs diffs) {
return formatter.format(UserSession.get().locale(), diffs);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
index 4ca5d8ed13a..36e7e6de7c1 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
@@ -19,11 +19,9 @@
*/
package org.sonar.server.issue;
-import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.HashMultiset;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Multiset;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.ServerComponent;
@@ -66,8 +64,6 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
-import static com.google.common.collect.Lists.newArrayList;
-
public class IssueService implements ServerComponent {
private final DbClient dbClient;
@@ -333,34 +329,6 @@ public class IssueService implements ServerComponent {
return indexClient.get(IssueIndex.class).search(query, options);
}
- /**
- * Used by the bulk change : first load issues from E/S to load only authorized issues then load issues from DB in order to update them.
- * TODO move it to the IssueBulkChangeService when OldIssueService will be removed
- */
- public List<Issue> search(List<String> issueKeys) {
- // Load from index to check permission
- List<Issue> authorizedIndexIssues = search(IssueQuery.builder().issueKeys(issueKeys).build(), new QueryContext().setMaxLimit()).getHits();
- List<String> authorizedIssueKeys = newArrayList(Iterables.transform(authorizedIndexIssues, new Function<Issue, String>() {
- @Override
- public String apply(@Nullable Issue input) {
- return input != null ? input.key() : null;
- }
- }));
-
- DbSession session = dbClient.openSession(false);
- try {
- List<IssueDto> issueDtos = dbClient.issueDao().getByKeys(session, authorizedIssueKeys);
- return newArrayList(Iterables.transform(issueDtos, new Function<IssueDto, Issue>() {
- @Override
- public Issue apply(@Nullable IssueDto input) {
- return input != null ? input.toDefaultIssue() : null;
- }
- }));
- } finally {
- session.close();
- }
- }
-
private void verifyLoggedIn() {
UserSession.get().checkLoggedIn();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/PublicRubyIssueService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/PublicRubyIssueService.java
deleted file mode 100644
index cdf5a2fb24b..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/PublicRubyIssueService.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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.Function;
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import org.sonar.api.issue.IssueFinder;
-import org.sonar.api.issue.IssueQuery;
-import org.sonar.api.issue.IssueQueryResult;
-import org.sonar.api.issue.RubyIssueService;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.web.UserRole;
-import org.sonar.server.issue.filter.IssueFilterParameters;
-import org.sonar.server.util.RubyUtils;
-
-import javax.annotation.Nullable;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Facade of issue components for JRuby on Rails webapp
- *
- * @since 3.6
- */
-public class PublicRubyIssueService implements RubyIssueService {
-
- private final IssueFinder finder;
-
- public PublicRubyIssueService(IssueFinder f) {
- this.finder = f;
- }
-
- /**
- * Requires the role {@link org.sonar.api.web.UserRole#USER}
- */
- @Override
- public IssueQueryResult find(String issueKey) {
- return finder.find(
- IssueQuery.builder()
- .issueKeys(Arrays.asList(issueKey))
- .requiredRole(UserRole.USER)
- .build());
- }
-
- /**
- * Requires the role {@link org.sonar.api.web.UserRole#USER}
- */
- @Override
- public IssueQueryResult find(Map<String, Object> params) {
- return finder.find(toQuery(params));
- }
-
- static IssueQuery toQuery(Map<String, Object> props) {
- IssueQuery.Builder builder = IssueQuery.builder()
- .requiredRole(UserRole.USER)
- .issueKeys(RubyUtils.toStrings(props.get(IssueFilterParameters.ISSUES)))
- .severities(RubyUtils.toStrings(props.get(IssueFilterParameters.SEVERITIES)))
- .statuses(RubyUtils.toStrings(props.get(IssueFilterParameters.STATUSES)))
- .resolutions(RubyUtils.toStrings(props.get(IssueFilterParameters.RESOLUTIONS)))
- .resolved(RubyUtils.toBoolean(props.get(IssueFilterParameters.RESOLVED)))
- .components(RubyUtils.toStrings(props.get(IssueFilterParameters.COMPONENTS)))
- .componentRoots(RubyUtils.toStrings(props.get(IssueFilterParameters.COMPONENT_ROOTS)))
- .rules(toRules(props.get(IssueFilterParameters.RULES)))
- .actionPlans(RubyUtils.toStrings(props.get(IssueFilterParameters.ACTION_PLANS)))
- .reporters(RubyUtils.toStrings(props.get(IssueFilterParameters.REPORTERS)))
- .assignees(RubyUtils.toStrings(props.get(IssueFilterParameters.ASSIGNEES)))
- .languages(RubyUtils.toStrings(props.get(IssueFilterParameters.LANGUAGES)))
- .assigned(RubyUtils.toBoolean(props.get(IssueFilterParameters.ASSIGNED)))
- .planned(RubyUtils.toBoolean(props.get(IssueFilterParameters.PLANNED)))
- .hideRules(RubyUtils.toBoolean(props.get(IssueFilterParameters.HIDE_RULES)))
- .createdAt(RubyUtils.toDate(props.get(IssueFilterParameters.CREATED_AT)))
- .createdAfter(RubyUtils.toDate(props.get(IssueFilterParameters.CREATED_AFTER)))
- .createdBefore(RubyUtils.toDate(props.get(IssueFilterParameters.CREATED_BEFORE)))
- .pageSize(RubyUtils.toInteger(props.get(IssueFilterParameters.PAGE_SIZE)))
- .pageIndex(RubyUtils.toInteger(props.get(IssueFilterParameters.PAGE_INDEX)));
- String sort = (String) props.get(IssueFilterParameters.SORT);
- if (!Strings.isNullOrEmpty(sort)) {
- builder.sort(sort);
- builder.asc(RubyUtils.toBoolean(props.get(IssueFilterParameters.ASC)));
- }
- return builder.build();
- }
-
- @SuppressWarnings("unchecked")
- static Collection<RuleKey> toRules(Object o) {
- Collection<RuleKey> result = null;
- if (o != null) {
- if (o instanceof List) {
- // assume that it contains only strings
- result = stringsToRules((List<String>) o);
- } else if (o instanceof String) {
- result = stringsToRules(Lists.newArrayList(Splitter.on(',').omitEmptyStrings().split((String) o)));
- }
- }
- return result;
- }
-
- private static Collection<RuleKey> stringsToRules(Collection<String> o) {
- return Collections2.transform(o, new Function<String, RuleKey>() {
- @Override
- public RuleKey apply(@Nullable String s) {
- return s != null ? RuleKey.parse(s) : null;
- }
- });
- }
-
-
- public void start() {
- // used to force pico to instantiate the singleton at startup
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterResult.java b/server/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterResult.java
deleted file mode 100644
index 0b10ad5f66c..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterResult.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.filter;
-
-import org.sonar.api.issue.IssueQuery;
-import org.sonar.api.issue.IssueQueryResult;
-
-/**
- * @since 3.7
- */
-public class IssueFilterResult {
-
- private IssueQueryResult issueQueryResult;
- private IssueQuery issueQuery;
-
- public IssueFilterResult(IssueQueryResult issueQueryResult, IssueQuery issueQuery) {
- this.issueQueryResult = issueQueryResult;
- this.issueQuery = issueQuery;
- }
-
- public IssueQueryResult result() {
- return issueQueryResult;
- }
-
- public IssueQuery query() {
- return issueQuery;
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
index b5cec4f65c8..085a8582f78 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
@@ -488,9 +488,7 @@ class ServerComponents {
pico.addSingleton(FunctionExecutor.class);
pico.addSingleton(IssueWorkflow.class);
pico.addSingleton(IssueCommentService.class);
- pico.addSingleton(DefaultIssueFinder.class);
pico.addSingleton(IssueStatsFinder.class);
- pico.addSingleton(PublicRubyIssueService.class);
pico.addSingleton(InternalRubyIssueService.class);
pico.addSingleton(IssueChangelogService.class);
pico.addSingleton(IssueNotifications.class);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java
deleted file mode 100644
index 738de5c4c63..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * 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.collect.Lists;
-import org.apache.ibatis.session.SqlSession;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
-import org.sonar.api.issue.ActionPlan;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueQuery;
-import org.sonar.api.issue.IssueQueryResult;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.user.User;
-import org.sonar.api.user.UserFinder;
-import org.sonar.api.utils.Duration;
-import org.sonar.core.component.ComponentDto;
-import org.sonar.core.issue.DefaultActionPlan;
-import org.sonar.core.issue.db.IssueChangeDao;
-import org.sonar.core.issue.db.IssueDao;
-import org.sonar.core.issue.db.IssueDto;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.user.DefaultUser;
-import org.sonar.server.issue.actionplan.ActionPlanService;
-import org.sonar.server.rule.DefaultRuleFinder;
-
-import java.util.Collections;
-import java.util.List;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.Sets.newHashSet;
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyCollection;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyListOf;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.*;
-
-public class
- DefaultIssueFinderTest {
-
- private static final int HOURS_IN_DAY = 8;
-
- MyBatis mybatis = mock(MyBatis.class);
- IssueDao issueDao = mock(IssueDao.class);
- IssueChangeDao issueChangeDao = mock(IssueChangeDao.class);
- DefaultRuleFinder ruleFinder = mock(DefaultRuleFinder.class);
- ResourceDao resourceDao = mock(ResourceDao.class);
- ActionPlanService actionPlanService = mock(ActionPlanService.class);
- UserFinder userFinder = mock(UserFinder.class);
- DefaultIssueFinder finder;
-
- @Before
- public void setUp() throws Exception {
- Settings settings = new Settings();
- settings.setProperty(CoreProperties.HOURS_IN_DAY, HOURS_IN_DAY);
- finder = new DefaultIssueFinder(mybatis, issueDao, issueChangeDao, ruleFinder, userFinder, resourceDao, actionPlanService);
- }
-
- @Test
- public void find_issues() {
- IssueQuery query = IssueQuery.builder().build();
-
- IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l)
- .setComponentKey("Action.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123l).setRootComponentId(100l)
- .setComponentKey("Action.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- List<IssueDto> dtoList = newArrayList(issue1, issue2);
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
-
- IssueQueryResult results = finder.find(query);
- verify(issueDao).selectIssueIds(eq(query), anyInt(), any(SqlSession.class));
-
- assertThat(results.issues()).hasSize(2);
- DefaultIssue issue = (DefaultIssue) results.issues().iterator().next();
- assertThat(issue.componentKey()).isEqualTo("Action.java");
- assertThat(issue.projectKey()).isEqualTo("struts");
- assertThat(issue.ruleKey().toString()).isEqualTo("squid:AvoidCycle");
- }
-
- @Test
- public void find_paginate_result() {
- IssueQuery query = IssueQuery.builder().pageSize(1).pageIndex(1).build();
-
- IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l)
- .setComponentKey("Action.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(135l).setRootComponentId(100l)
- .setComponentKey("Phases.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- List<IssueDto> dtoList = newArrayList(issue1, issue2);
- when(issueDao.selectIssueIds(eq(query), anyInt(), any(SqlSession.class))).thenReturn(dtoList);
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
-
- IssueQueryResult results = finder.find(query);
- assertThat(results.paging().offset()).isEqualTo(0);
- assertThat(results.paging().total()).isEqualTo(2);
- assertThat(results.paging().pages()).isEqualTo(2);
-
- // Only one result is expected because the limit is 1
- verify(issueDao).selectByIds(eq(newHashSet(1L)), any(SqlSession.class));
- }
-
- @Test
- public void find_by_key() {
- IssueDto issueDto = new IssueDto().setId(1L).setRuleId(1).setComponentId(1l).setRootComponentId(100l)
- .setComponentKey("Action.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- when(issueDao.selectByKey("ABCDE")).thenReturn(issueDto);
-
- Issue issue = finder.findByKey("ABCDE");
- assertThat(issue).isNotNull();
- assertThat(issue.componentKey()).isEqualTo("Action.java");
- assertThat(issue.ruleKey().toString()).isEqualTo("squid:AvoidCycle");
- }
-
- @Test
- public void get_rule_from_result() {
- Rule rule = Rule.create().setRepositoryKey("squid").setKey("AvoidCycle");
- when(ruleFinder.findByIds(anyCollection())).thenReturn(newArrayList(rule));
-
- IssueQuery query = IssueQuery.builder().build();
-
- IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l)
- .setComponentKey("Action.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123l).setRootComponentId(100l)
- .setComponentKey("Action.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- List<IssueDto> dtoList = newArrayList(issue1, issue2);
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
-
- IssueQueryResult results = finder.find(query);
- assertThat(results.issues()).hasSize(2);
- Issue issue = results.issues().iterator().next();
- assertThat(results.issues()).hasSize(2);
- assertThat(results.rule(issue)).isEqualTo(rule);
- assertThat(results.rules()).hasSize(1);
- }
-
- @Test
- public void get_no_rule_from_result_with_hide_rules_param() {
- Rule rule = Rule.create().setRepositoryKey("squid").setKey("AvoidCycle");
- when(ruleFinder.findByIds(anyCollection())).thenReturn(newArrayList(rule));
-
- IssueQuery query = IssueQuery.builder().hideRules(true).build();
-
- IssueDto issue = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l)
- .setComponentKey("Action.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(newArrayList(issue));
-
- IssueQueryResult results = finder.find(query);
- Issue result = results.issues().iterator().next();
- assertThat(results.rule(result)).isNull();
- assertThat(results.rules()).isEmpty();
- }
-
- @Test
- public void get_component_from_result() {
- ComponentDto component = new ComponentDto().setId(1L).setKey("Action.java");
- when(resourceDao.selectComponentsByIds(anyCollection())).thenReturn(newArrayList(component));
-
- IssueQuery query = IssueQuery.builder().build();
-
- IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l)
- .setComponentKey("Action.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123l).setRootComponentId(100l)
- .setComponentKey("Action.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- List<IssueDto> dtoList = newArrayList(issue1, issue2);
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
-
- IssueQueryResult results = finder.find(query);
- assertThat(results.issues()).hasSize(2);
- assertThat(results.components()).hasSize(1);
- Issue issue = results.issues().iterator().next();
- assertThat(results.component(issue)).isEqualTo(component);
- }
-
- @Test
- public void get_project_from_result() {
- ComponentDto project = new ComponentDto().setId(1L).setKey("struts");
- when(resourceDao.selectComponentsByIds(anyCollection())).thenReturn(newArrayList(project));
-
- IssueQuery query = IssueQuery.builder().build();
-
- IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l)
- .setComponentKey("Action.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123l).setRootComponentId(100l)
- .setComponentKey("Action.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- List<IssueDto> dtoList = newArrayList(issue1, issue2);
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
-
- IssueQueryResult results = finder.find(query);
- assertThat(results.issues()).hasSize(2);
- assertThat(results.projects()).hasSize(1);
- Issue issue = results.issues().iterator().next();
- assertThat(results.project(issue)).isEqualTo(project);
- }
-
- @Test
- public void get_action_plans_from_result() {
- ActionPlan actionPlan1 = DefaultActionPlan.create("Short term").setKey("A");
- ActionPlan actionPlan2 = DefaultActionPlan.create("Long term").setKey("B");
-
- IssueQuery query = IssueQuery.builder().build();
-
- IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l).setKee("ABC").setActionPlanKey("A")
- .setComponentKey("Action.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123l).setRootComponentId(100l).setKee("DEF").setActionPlanKey("B")
- .setComponentKey("Action.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- List<IssueDto> dtoList = newArrayList(issue1, issue2);
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
- when(actionPlanService.findByKeys(anyCollection())).thenReturn(newArrayList(actionPlan1, actionPlan2));
-
- IssueQueryResult results = finder.find(query);
- assertThat(results.issues()).hasSize(2);
- assertThat(results.actionPlans()).hasSize(2);
- Issue issue = results.issues().iterator().next();
- assertThat(results.actionPlan(issue)).isNotNull();
- }
-
- @Test
- public void get_user_from_result() {
- when(userFinder.findByLogins(anyListOf(String.class))).thenReturn(Lists.<User>newArrayList(
- new DefaultUser().setLogin("perceval").setName("Perceval"),
- new DefaultUser().setLogin("arthur").setName("Roi Arthur")
- ));
-
- IssueQuery query = IssueQuery.builder().build();
-
- IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l).setKee("ABC").setAssignee("perceval")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123l).setRootComponentId(100l).setKee("DEF").setReporter("arthur")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN");
- List<IssueDto> dtoList = newArrayList(issue1, issue2);
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
-
- IssueQueryResult results = finder.find(query);
- assertThat(results.issues()).hasSize(2);
-
- assertThat(results.users()).hasSize(2);
- assertThat(results.user("perceval").name()).isEqualTo("Perceval");
- assertThat(results.user("arthur").name()).isEqualTo("Roi Arthur");
- }
-
- @Test
- public void get_empty_result_when_no_issue() {
- IssueQuery query = IssueQuery.builder().build();
- when(issueDao.selectIssueIds(eq(query), anyInt(), any(SqlSession.class))).thenReturn(Collections.<IssueDto>emptyList());
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(Collections.<IssueDto>emptyList());
-
- IssueQueryResult results = finder.find(query);
- assertThat(results.issues()).isEmpty();
- assertThat(results.rules()).isEmpty();
- assertThat(results.components()).isEmpty();
- assertThat(results.actionPlans()).isEmpty();
- }
-
- @Test
- public void find_issue_with_technical_debt() {
- IssueQuery query = IssueQuery.builder().build();
-
- IssueDto issue = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l)
- .setComponentKey("Action.java")
- .setRootComponentKey("struts")
- .setRuleKey("squid", "AvoidCycle")
- .setStatus("OPEN").setResolution("OPEN")
- .setDebt(10L);
- List<IssueDto> dtoList = newArrayList(issue);
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
-
- IssueQueryResult results = finder.find(query);
- verify(issueDao).selectIssueIds(eq(query), anyInt(), any(SqlSession.class));
-
- assertThat(results.issues()).hasSize(1);
- DefaultIssue result = (DefaultIssue) results.issues().iterator().next();
- assertThat(result.debt()).isEqualTo(Duration.create(10L));
- }
-
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceTest.java
index afc86cc1724..15d996feea0 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceTest.java
@@ -20,9 +20,11 @@
package org.sonar.server.issue;
+import com.google.common.collect.Lists;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.IssueQuery;
import org.sonar.api.issue.condition.Condition;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.issue.internal.IssueChangeContext;
@@ -31,6 +33,7 @@ import org.sonar.api.resources.Scopes;
import org.sonar.api.rules.Rule;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.issue.IssueNotifications;
+import org.sonar.core.issue.db.IssueDto;
import org.sonar.core.issue.db.IssueStorage;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.preview.PreviewCache;
@@ -38,7 +41,10 @@ import org.sonar.server.component.db.ComponentDao;
import org.sonar.server.db.DbClient;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.UnauthorizedException;
+import org.sonar.server.issue.db.IssueDao;
import org.sonar.server.rule.DefaultRuleFinder;
+import org.sonar.server.rule.RuleTesting;
+import org.sonar.server.search.QueryContext;
import org.sonar.server.user.MockUserSession;
import org.sonar.server.user.UserSession;
@@ -61,6 +67,7 @@ public class IssueBulkChangeServiceTest {
DbClient dbClient = mock(DbClient.class);
DbSession dbSession = mock(DbSession.class);
+ IssueDao issueDao = mock(IssueDao.class);
IssueService issueService = mock(IssueService.class);
IssueStorage issueStorage = mock(IssueStorage.class);
DefaultRuleFinder ruleFinder = mock(DefaultRuleFinder.class);
@@ -82,6 +89,7 @@ public class IssueBulkChangeServiceTest {
public void before() {
when(dbClient.openSession(false)).thenReturn(dbSession);
when(dbClient.componentDao()).thenReturn(componentDao);
+ when(dbClient.issueDao()).thenReturn(issueDao);
rule = Rule.create("repo", "key");
when(ruleFinder.findByKeys(newHashSet(rule.ruleKey()))).thenReturn(newArrayList(rule));
@@ -102,12 +110,13 @@ public class IssueBulkChangeServiceTest {
.setLongName("My Component");
when(componentDao.getByKeys(dbSession, newHashSet(file.key()))).thenReturn(newArrayList(file));
- issue = new DefaultIssue()
- .setKey("ABCD")
- .setRuleKey(rule.ruleKey())
- .setProjectKey(project.key())
- .setComponentKey(file.key());
- when(issueService.search(anyListOf(String.class))).thenReturn(newArrayList((Issue) issue));
+ IssueDto issueDto = IssueTesting.newDto(RuleTesting.newDto(rule.ruleKey()).setId(50), file, project).setKee("ABCD");
+ issue = issueDto.toDefaultIssue();
+
+ org.sonar.server.search.Result<Issue> result = mock(org.sonar.server.search.Result.class);
+ when(result.getHits()).thenReturn(newArrayList((Issue) issue));
+ when(issueService.search(any(IssueQuery.class), any(QueryContext.class))).thenReturn(result);
+ when(issueDao.getByKeys(dbSession, newArrayList(issue.key()))).thenReturn(newArrayList(issueDto));
actions = newArrayList();
service = new IssueBulkChangeService(dbClient, issueService, issueStorage, ruleFinder, issueNotifications, actions, mock(PreviewCache.class));
@@ -176,7 +185,13 @@ public class IssueBulkChangeServiceTest {
@Test
public void should_execute_bulk_change_with_comment_only_on_changed_issues() {
- when(issueService.search(anyListOf(String.class))).thenReturn(newArrayList((Issue) new DefaultIssue().setKey("ABCD"), new DefaultIssue().setKey("EFGH")));
+ IssueDto issueDto1 = IssueTesting.newDto(RuleTesting.newDto(rule.ruleKey()).setId(50), file, project).setKee("ABCD");
+ IssueDto issueDto2 = IssueTesting.newDto(RuleTesting.newDto(rule.ruleKey()).setId(50), file, project).setKee("EFGH");
+
+ org.sonar.server.search.Result<Issue> resultIssues = mock(org.sonar.server.search.Result.class);
+ when(resultIssues.getHits()).thenReturn(Lists.<Issue>newArrayList(issueDto1.toDefaultIssue(), issueDto2.toDefaultIssue()));
+ when(issueService.search(any(IssueQuery.class), any(QueryContext.class))).thenReturn(resultIssues);
+ when(issueDao.getByKeys(dbSession, newArrayList("ABCD", "EFGH"))).thenReturn(newArrayList(issueDto1, issueDto2));
Map<String, Object> properties = newHashMap();
properties.put("issues", "ABCD,EFGH");
@@ -205,7 +220,7 @@ public class IssueBulkChangeServiceTest {
// Only one issue will receive the comment
verify(assignAction, times(1)).execute(anyMap(), any(IssueBulkChangeService.ActionContext.class));
- verify(issueStorage).save(eq(issue));
+ verify(issueStorage).save(eq(issueDto1.toDefaultIssue()));
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueChangelogServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueChangelogServiceTest.java
index c4c9ca144b8..92565268338 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueChangelogServiceTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueChangelogServiceTest.java
@@ -24,26 +24,18 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueQuery;
-import org.sonar.api.issue.IssueQueryResult;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.issue.internal.FieldDiffs;
import org.sonar.api.user.User;
import org.sonar.api.user.UserFinder;
-import org.sonar.core.issue.DefaultIssueQueryResult;
import org.sonar.core.issue.db.IssueChangeDao;
import org.sonar.core.user.DefaultUser;
-import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.user.MockUserSession;
import java.util.Arrays;
-import java.util.Collections;
import java.util.Locale;
-import static com.google.common.collect.Lists.newArrayList;
import static org.fest.assertions.Assertions.assertThat;
-import static org.fest.assertions.Fail.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
@@ -57,7 +49,7 @@ public class IssueChangelogServiceTest {
UserFinder userFinder;
@Mock
- DefaultIssueFinder issueFinder;
+ IssueService issueService;
@Mock
IssueChangelogFormatter formatter;
@@ -66,7 +58,7 @@ public class IssueChangelogServiceTest {
@Before
public void setUp() throws Exception {
- service = new IssueChangelogService(changeDao, userFinder, issueFinder, formatter);
+ service = new IssueChangelogService(changeDao, userFinder, issueService, formatter);
}
@Test
@@ -77,8 +69,7 @@ public class IssueChangelogServiceTest {
User arthur = new DefaultUser().setLogin("arthur").setName("Arthur");
when(userFinder.findByLogins(Arrays.asList("arthur"))).thenReturn(Arrays.asList(arthur));
- IssueQueryResult issueQueryResult = new DefaultIssueQueryResult(newArrayList((Issue) new DefaultIssue().setKey("ABCDE")));
- when(issueFinder.find(any(IssueQuery.class))).thenReturn(issueQueryResult);
+ when(issueService.getByKey("ABCDE")).thenReturn(new DefaultIssue().setKey("ABCDE"));
IssueChangelog changelog = service.changelog("ABCDE");
@@ -89,21 +80,6 @@ public class IssueChangelogServiceTest {
}
@Test
- public void not_load_changelog_on_unkown_issue() throws Exception {
- try {
- IssueQueryResult issueQueryResult = new DefaultIssueQueryResult(Collections.<Issue>emptyList());
- when(issueFinder.find(any(IssueQuery.class))).thenReturn(issueQueryResult);
-
- service.changelog("ABCDE");
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(NotFoundException.class);
- verifyNoMoreInteractions(changeDao);
- verifyNoMoreInteractions(userFinder);
- }
- }
-
- @Test
public void format_diffs() throws Exception {
FieldDiffs diffs = new FieldDiffs().setUserLogin("arthur").setDiff("severity", "MAJOR", "BLOCKER");
MockUserSession.set();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java
index 21f4190dcfa..57644daf2d9 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java
@@ -61,7 +61,6 @@ import java.util.Date;
import java.util.List;
import java.util.UUID;
-import static com.google.common.collect.Lists.newArrayList;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;
@@ -389,7 +388,7 @@ public class IssueServiceMediumTest {
tester.get(IssueDao.class).insert(session, issue);
session.commit();
- List<Issue> result = service.search(newArrayList(issue.getKey()));
+ List<Issue> result = service.search(IssueQuery.builder().build(), new QueryContext()).getHits();
assertThat(result).hasSize(1);
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/PublicRubyIssueServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/PublicRubyIssueServiceTest.java
deleted file mode 100644
index 95bc3a3fcf2..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/PublicRubyIssueServiceTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import org.junit.Test;
-import org.mockito.ArgumentMatcher;
-import org.sonar.api.issue.IssueFinder;
-import org.sonar.api.issue.IssueQuery;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.api.web.UserRole;
-
-import java.util.Map;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.Maps.newHashMap;
-import static java.util.Arrays.asList;
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.*;
-
-public class PublicRubyIssueServiceTest {
-
- IssueFinder finder = mock(IssueFinder.class);
- PublicRubyIssueService facade = new PublicRubyIssueService(finder);
-
- @Test
- public void find_by_issue_keys() throws Exception {
- facade.find("ABCDE");
- verify(finder).find(argThat(new ArgumentMatcher<IssueQuery>() {
- @Override
- public boolean matches(Object o) {
- IssueQuery query = (IssueQuery) o;
- return query.issueKeys().contains("ABCDE") && UserRole.USER.equals(query.requiredRole());
- }
- }));
- }
-
- @Test
- public void find_by_params() throws Exception {
- facade.find(ImmutableMap.<String, Object>of("issues", Lists.newArrayList("ABCDE")));
- verify(finder).find(argThat(new ArgumentMatcher<IssueQuery>() {
- @Override
- public boolean matches(Object o) {
- IssueQuery query = (IssueQuery) o;
- return query.issueKeys().contains("ABCDE") && UserRole.USER.equals(query.requiredRole());
- }
- }));
- }
-
- @Test
- public void create_query_from_parameters() {
- Map<String, Object> map = newHashMap();
- map.put("issues", newArrayList("ABCDE1234"));
- map.put("severities", newArrayList("MAJOR", "MINOR"));
- map.put("statuses", newArrayList("CLOSED"));
- map.put("resolutions", newArrayList("FALSE-POSITIVE"));
- map.put("resolved", true);
- map.put("components", newArrayList("org.apache"));
- map.put("componentRoots", newArrayList("org.sonar"));
- map.put("reporters", newArrayList("marilyn"));
- map.put("assignees", newArrayList("joanna"));
- map.put("languages", newArrayList("xoo"));
- map.put("assigned", true);
- map.put("planned", true);
- map.put("hideRules", true);
- map.put("createdAfter", "2013-04-16T09:08:24+0200");
- map.put("createdBefore", "2013-04-17T09:08:24+0200");
- map.put("rules", "squid:AvoidCycle,findbugs:NullReference");
- map.put("pageSize", 10l);
- map.put("pageIndex", 50);
- map.put("sort", "CREATION_DATE");
- map.put("asc", true);
-
- IssueQuery query = new PublicRubyIssueService(finder).toQuery(map);
- assertThat(query.issueKeys()).containsOnly("ABCDE1234");
- assertThat(query.severities()).containsOnly("MAJOR", "MINOR");
- assertThat(query.statuses()).containsOnly("CLOSED");
- assertThat(query.resolutions()).containsOnly("FALSE-POSITIVE");
- assertThat(query.resolved()).isTrue();
- assertThat(query.components()).containsOnly("org.apache");
- assertThat(query.componentRoots()).containsOnly("org.sonar");
- assertThat(query.reporters()).containsOnly("marilyn");
- assertThat(query.assignees()).containsOnly("joanna");
- assertThat(query.languages()).containsOnly("xoo");
- assertThat(query.assigned()).isTrue();
- assertThat(query.planned()).isTrue();
- assertThat(query.hideRules()).isTrue();
- assertThat(query.rules()).hasSize(2);
- assertThat(query.createdAfter()).isEqualTo(DateUtils.parseDateTime("2013-04-16T09:08:24+0200"));
- assertThat(query.createdBefore()).isEqualTo(DateUtils.parseDateTime("2013-04-17T09:08:24+0200"));
- assertThat(query.pageSize()).isEqualTo(10);
- assertThat(query.pageIndex()).isEqualTo(50);
- assertThat(query.sort()).isEqualTo(IssueQuery.SORT_BY_CREATION_DATE);
- assertThat(query.asc()).isTrue();
- }
-
- @Test
- public void parse_list_of_rules() {
- assertThat(PublicRubyIssueService.toRules(null)).isNull();
- assertThat(PublicRubyIssueService.toRules("")).isEmpty();
- assertThat(PublicRubyIssueService.toRules("squid:AvoidCycle")).containsOnly(RuleKey.of("squid", "AvoidCycle"));
- assertThat(PublicRubyIssueService.toRules("squid:AvoidCycle,findbugs:NullRef")).containsOnly(RuleKey.of("squid", "AvoidCycle"), RuleKey.of("findbugs", "NullRef"));
- assertThat(PublicRubyIssueService.toRules(asList("squid:AvoidCycle", "findbugs:NullRef"))).containsOnly(RuleKey.of("squid", "AvoidCycle"), RuleKey.of("findbugs", "NullRef"));
- }
-
- @Test
- public void start() throws Exception {
- facade.start();
- // nothing is done
- verifyZeroInteractions(finder);
- }
-}
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/models/api.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/models/api.rb
index 0c0e6bcda66..0e1ee3ebc14 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/models/api.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/models/api.rb
@@ -22,12 +22,6 @@
# as an API and can evolve through time.
class Api
- # See the javadoc of org.sonar.api.issue.RubyIssueService.
- # Since 3.6
- def self.issues
- Internal.issues_api
- end
-
# See the javadoc of org.sonar.api.user.RubyUserService
# Since 3.6
def self.users
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/models/internal.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/models/internal.rb
index d2bd4ed0bf0..dc2e9aaa395 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/models/internal.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/models/internal.rb
@@ -26,10 +26,6 @@ class Internal
component(Java::OrgSonarServerIssue::InternalRubyIssueService.java_class)
end
- def self.issues_api
- component(Java::OrgSonarApiIssue::RubyIssueService.java_class)
- end
-
def self.text
component(Java::OrgSonarServerText::RubyTextService.java_class)
end
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
deleted file mode 100644
index aa35a24493f..00000000000
--- a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueQueryResult.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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.core.issue;
-
-import com.google.common.collect.Maps;
-import org.sonar.api.component.Component;
-import org.sonar.api.issue.ActionPlan;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueQueryResult;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.user.User;
-import org.sonar.api.utils.Paging;
-
-import javax.annotation.CheckForNull;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-public class DefaultIssueQueryResult implements IssueQueryResult {
-
- private List<Issue> issues;
- private final Map<RuleKey, Rule> rulesByKey = Maps.newHashMap();
- private final Map<String, Component> componentsByKey = Maps.newHashMap();
- private final Map<String, Component> projectsByKey = Maps.newHashMap();
- private final Map<String, ActionPlan> actionPlansByKey = Maps.newHashMap();
- private final Map<String, User> usersByLogin = Maps.newHashMap();
- private boolean maxResultsReached;
- private Paging paging;
-
- public DefaultIssueQueryResult(List<Issue> issues){
- this.issues = issues;
- }
-
- public DefaultIssueQueryResult addRules(Collection<Rule> rules){
- for (Rule rule : rules) {
- rulesByKey.put(rule.ruleKey(), rule);
- }
- return this;
- }
-
- public DefaultIssueQueryResult addComponents(Collection<Component> components){
- for (Component component : components) {
- componentsByKey.put(component.key(), component);
- }
- return this;
- }
-
- public DefaultIssueQueryResult addProjects(Collection<Component> projects){
- for (Component project : projects) {
- projectsByKey.put(project.key(), project);
- }
- return this;
- }
-
- public DefaultIssueQueryResult addActionPlans(Collection<ActionPlan> actionPlans){
- for (ActionPlan actionPlan : actionPlans) {
- actionPlansByKey.put(actionPlan.key(), actionPlan);
- }
- return this;
- }
-
- public DefaultIssueQueryResult addUsers(Collection<User> users){
- for (User user : users) {
- usersByLogin.put(user.login(), user);
- }
- return this;
- }
-
- public DefaultIssueQueryResult setMaxResultsReached(boolean maxResultsReached){
- this.maxResultsReached = maxResultsReached;
- return this;
- }
-
- public DefaultIssueQueryResult setPaging(Paging paging){
- this.paging = paging;
- return this;
- }
-
- @Override
- public List<Issue> issues() {
- return issues;
- }
-
- @Override
- public Issue first() {
- if (issues != null && !issues.isEmpty()) {
- return issues.get(0);
- }
- throw new IllegalStateException("No issue found");
- }
-
- @Override
- public Rule rule(Issue issue) {
- return rulesByKey.get(issue.ruleKey());
- }
-
- @Override
- public Collection<Rule> rules() {
- return rulesByKey.values();
- }
-
- @Override
- public Component component(Issue issue) {
- return componentsByKey.get(issue.componentKey());
- }
-
- @Override
- public Collection<Component> components() {
- return componentsByKey.values();
- }
-
- @Override
- public Component project(Issue issue) {
- return projectsByKey.get(((DefaultIssue) issue).projectKey());
- }
-
- @Override
- public Collection<Component> projects() {
- return projectsByKey.values();
- }
-
- @Override
- public ActionPlan actionPlan(Issue issue) {
- return actionPlansByKey.get(issue.actionPlanKey());
- }
-
- @Override
- public Collection<ActionPlan> actionPlans() {
- return actionPlansByKey.values();
- }
-
- @Override
- public Collection<User> users() {
- return usersByLogin.values();
- }
-
- @Override
- @CheckForNull
- public User user(String login) {
- return usersByLogin.get(login);
- }
-
- @Override
- public boolean maxResultsReached() {
- return maxResultsReached;
- }
-
- @Override
- public Paging paging() {
- return paging;
- }
-
-
-}
diff --git a/sonar-core/src/main/java/org/sonar/core/issue/IssueNotifications.java b/sonar-core/src/main/java/org/sonar/core/issue/IssueNotifications.java
index 5cfec677dd0..d084741ac90 100644
--- a/sonar-core/src/main/java/org/sonar/core/issue/IssueNotifications.java
+++ b/sonar-core/src/main/java/org/sonar/core/issue/IssueNotifications.java
@@ -24,7 +24,6 @@ import com.google.common.collect.Maps;
import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
import org.sonar.api.component.Component;
-import org.sonar.api.issue.IssueQueryResult;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.issue.internal.FieldDiffs;
import org.sonar.api.issue.internal.IssueChangeContext;
@@ -69,13 +68,6 @@ public class IssueNotifications implements BatchComponent, ServerComponent {
}
@CheckForNull
- public List<Notification> sendChanges(DefaultIssue issue, IssueChangeContext context, IssueQueryResult queryResult) {
- Map<DefaultIssue, Rule> issues = Maps.newHashMap();
- issues.put(issue, queryResult.rule(issue));
- return sendChanges(issue, context, queryResult.rule(issue), queryResult.project(issue), queryResult.component(issue));
- }
-
- @CheckForNull
public List<Notification> sendChanges(DefaultIssue issue, IssueChangeContext context, Rule rule, Component project, @Nullable Component component) {
return sendChanges(issue, context, rule, project, component, null);
}
@@ -96,22 +88,15 @@ public class IssueNotifications implements BatchComponent, ServerComponent {
notifications.add(notification);
}
}
- notificationsManager.scheduleForSending(notifications);
- return notifications;
- }
-
- @CheckForNull
- public Notification sendChanges(DefaultIssue issue, IssueChangeContext context, IssueQueryResult queryResult, @Nullable String comment) {
- Notification notification = createChangeNotification(issue, context, queryResult.rule(issue), queryResult.project(issue), queryResult.component(issue), comment);
- if (notification != null) {
- notificationsManager.scheduleForSending(notification);
+ if (!notifications.isEmpty()) {
+ notificationsManager.scheduleForSending(notifications);
}
- return notification;
+ return notifications;
}
@CheckForNull
private Notification createChangeNotification(DefaultIssue issue, IssueChangeContext context, Rule rule, Component project,
- @Nullable Component component, @Nullable String comment) {
+ @Nullable Component component, @Nullable String comment) {
Notification notification = null;
if (comment != null || issue.mustSendNotifications()) {
FieldDiffs currentChange = issue.currentChange();
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
deleted file mode 100644
index b804e9d56d2..00000000000
--- a/sonar-core/src/test/java/org/sonar/core/issue/DefaultIssueQueryResultTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.core.issue;
-
-import org.junit.Test;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.fest.assertions.Assertions.assertThat;
-
-public class DefaultIssueQueryResultTest {
-
- @Test(expected = IllegalStateException.class)
- public void first_should_throw_exception_if_no_issues() {
- DefaultIssueQueryResult result = new DefaultIssueQueryResult(Collections.<Issue>emptyList());
- result.first();
- }
-
- @Test
- public void test_first_issue() {
- DefaultIssueQueryResult result = new DefaultIssueQueryResult(newArrayList((Issue) new DefaultIssue()));
- assertThat(result.first()).isNotNull();
-
- Issue first = new DefaultIssue();
- Issue second = new DefaultIssue();
- result = new DefaultIssueQueryResult(Arrays.asList(first, second));
- assertThat(result.first()).isSameAs(first);
- }
-}
diff --git a/sonar-core/src/test/java/org/sonar/core/issue/IssueNotificationsTest.java b/sonar-core/src/test/java/org/sonar/core/issue/IssueNotificationsTest.java
index 180948f8e0c..ca625c8dc81 100644
--- a/sonar-core/src/test/java/org/sonar/core/issue/IssueNotificationsTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/issue/IssueNotificationsTest.java
@@ -25,8 +25,6 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.api.component.Component;
-import org.sonar.api.issue.Issue;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.issue.internal.IssueChangeContext;
import org.sonar.api.notifications.Notification;
@@ -38,6 +36,7 @@ import org.sonar.core.component.ResourceComponent;
import java.util.Arrays;
import java.util.Date;
+import java.util.List;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.eq;
@@ -85,10 +84,8 @@ public class IssueNotificationsTest {
.setSendNotifications(true)
.setComponentKey("struts:Action")
.setProjectKey("struts");
- DefaultIssueQueryResult queryResult = new DefaultIssueQueryResult(Arrays.<Issue>asList(issue));
- queryResult.addProjects(Arrays.<Component>asList(new Project("struts")));
- Notification notification = issueNotifications.sendChanges(issue, context, queryResult).get(0);
+ Notification notification = issueNotifications.sendChanges(issue, context, null, new Project("struts"), null).get(0);
assertThat(notification.getFieldValue("message")).isEqualTo("the message");
assertThat(notification.getFieldValue("key")).isEqualTo("ABCDE");
@@ -112,15 +109,12 @@ public class IssueNotificationsTest {
.setAssignee("freddy")
.setComponentKey("struts:Action")
.setProjectKey("struts");
- DefaultIssueQueryResult queryResult = new DefaultIssueQueryResult(Arrays.<Issue>asList(issue));
- queryResult.addProjects(Arrays.<Component>asList(new Project("struts")));
-
- Notification notification = issueNotifications.sendChanges(issue, context, queryResult, "I don't know how to fix it?");
+ Notification notification = issueNotifications.sendChanges(issue, context, null, new Project("struts"), null, "I don't know how to fix it?").get(0);
assertThat(notification.getFieldValue("message")).isEqualTo("the message");
assertThat(notification.getFieldValue("key")).isEqualTo("ABCDE");
assertThat(notification.getFieldValue("comment")).isEqualTo("I don't know how to fix it?");
- Mockito.verify(manager).scheduleForSending(notification);
+ Mockito.verify(manager).scheduleForSending(eq(Arrays.asList(notification)));
}
@Test
@@ -134,11 +128,8 @@ public class IssueNotificationsTest {
.setSendNotifications(true)
.setComponentKey("struts:Action.java")
.setProjectKey("struts");
- DefaultIssueQueryResult queryResult = new DefaultIssueQueryResult(Arrays.<Issue>asList(issue));
- queryResult.addProjects(Arrays.<Component>asList(new Project("struts")));
- queryResult.addComponents(Arrays.<Component>asList(new ResourceComponent(File.create("Action.java", "Action.java", null, false).setEffectiveKey("struts:Action.java"))));
-
- Notification notification = issueNotifications.sendChanges(issue, context, queryResult).get(0);
+ Notification notification = issueNotifications.sendChanges(issue, context, null, new Project("struts"),
+ new ResourceComponent(File.create("Action.java", "Action.java", null, false).setEffectiveKey("struts:Action.java"))).get(0);
assertThat(notification.getFieldValue("message")).isEqualTo("the message");
assertThat(notification.getFieldValue("key")).isEqualTo("ABCDE");
@@ -157,12 +148,9 @@ public class IssueNotificationsTest {
.setKey("ABCDE")
.setComponentKey("struts:Action")
.setProjectKey("struts");
- DefaultIssueQueryResult queryResult = new DefaultIssueQueryResult(Arrays.<Issue>asList(issue));
- queryResult.addProjects(Arrays.<Component>asList(new Project("struts")));
-
- Notification notification = issueNotifications.sendChanges(issue, context, queryResult, null);
+ List<Notification> notifications = issueNotifications.sendChanges(issue, context, null, new Project("struts"), null);
- assertThat(notification).isNull();
+ assertThat(notifications).isEmpty();
Mockito.verifyZeroInteractions(manager);
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueFinder.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueFinder.java
deleted file mode 100644
index 7314539e6aa..00000000000
--- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueFinder.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.api.issue;
-
-import org.sonar.api.ServerComponent;
-
-/**
- * Search for issues. This IoC component can be used only by server-side extensions. {@link org.sonar.api.BatchExtension}s should
- * use the perspective {@link Issuable}.
- *
- * @since 3.6
- */
-public interface IssueFinder extends ServerComponent {
-
- IssueQueryResult find(IssueQuery query);
-
-}
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
deleted file mode 100644
index 37ea218345f..00000000000
--- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQueryResult.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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.api.issue;
-
-import org.sonar.api.component.Component;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.user.User;
-import org.sonar.api.utils.Paging;
-
-import javax.annotation.CheckForNull;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * @since 3.6
- * @deprecated since 5.0
- */
-@Deprecated
-public interface IssueQueryResult {
- /**
- * Non-null paginated list of issues.
- */
- List<Issue> issues();
-
- /**
- * Returns the first issue in the list.
- * @throws IllegalStateException if the list is empty.
- */
- Issue first();
-
- /**
- * Returns the rule associated to the given issue.
- */
- @Deprecated
- Rule rule(Issue issue);
-
- /**
- * The rules involved in the paginated {@link #issues()}.
- */
- @Deprecated
- Collection<Rule> rules();
-
- Component component(Issue issue);
-
- /**
- * The components involved in the paginated {@link #issues()}.
- */
- Collection<Component> components();
-
- Component project(Issue issue);
-
- /**
- * The projects involved in the paginated {@link #issues()}.
- */
- Collection<Component> projects();
-
- @CheckForNull
- @Deprecated
- ActionPlan actionPlan(Issue issue);
-
- /**
- * The action plans involved in the paginated {@link #issues()}.
- */
- @Deprecated
- Collection<ActionPlan> actionPlans();
-
- /**
- * The users involved in the paginated {@link #issues()}, for example people who added a comment, reported an issue
- * or are assigned to issues.
- */
- @Deprecated
- Collection<User> users();
-
- /**
- * Returns the user with the given login. Users that are not returned by {@link #users()} are ignored.
- */
- @CheckForNull
- @Deprecated
- 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
deleted file mode 100644
index a413aa80533..00000000000
--- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/RubyIssueService.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.api.issue;
-
-import org.sonar.api.ServerComponent;
-
-import java.util.Map;
-
-/**
- * Facade for JRuby on Rails extensions to request issues.
- * <p>
- * Reference from Ruby code : <code>Api.issues</code>
- * </p>
- *
- * @since 3.6
- */
-public interface RubyIssueService extends ServerComponent {
-
- /**
- * Search for an issue by its key.
- * <p/>
- * Ruby example: <code>result = Api.issues.find('ABCDE-12345')</code>
- */
- IssueQueryResult find(String issueKey);
-
- /**
- * Search for issues.
- * <p/>
- * Ruby example: <code>Api.issues.find({'statuses' => ['OPEN', 'RESOLVED'], 'assignees' => 'john,carla')}</code>
- * <p/>
- * <b>Keys of parameters must be Ruby strings but not symbols</b>. Multi-value parameters can be arrays (<code>['OPEN', 'RESOLVED']</code>) or
- * comma-separated list of strings (<code>'OPEN,RESOLVED'</code>).
- * <p/>
- * Optional parameters are:
- * <ul>
- * <li>'issues': list of issue keys</li>
- * <li>'severities': list of severity to match. See constants in {@link org.sonar.api.rule.Severity}</li>
- * <li>'statuses': list of status to match. See constants in {@link Issue}</li>
- * <li>'resolutions': list of resolutions to match. See constants in {@link Issue}</li>
- * <li>'resolved': true to match only resolved issues, false to match only unresolved issues. By default no filtering is done.</li>
- * <li>'components': list of component keys to match, for example 'org.apache.struts:struts:org.apache.struts.Action'</li>
- * <li>'componentRoots': list of keys of root components. All the issues related to descendants of these roots are returned.</li>
- * <li>'rules': list of keys of rules to match. Format is &lt;repository&gt;:&lt;rule&gt;, for example 'squid:AvoidCycles'</li>
- * <li>'actionPlans': list of keys of the action plans to match. Note that plan names are not accepted.</li>
- * <li>'planned': true to get only issues associated to an action plan, false to get only non associated issues. By default no filtering is done.</li>
- * <li>'reporters': list of reporter logins. Note that reporters are defined only on "manual" issues.</li>
- * <li>'assignees': list of assignee logins.</li>
- * <li>'assigned': true to get only assigned issues, false to get only not assigned issues. By default no filtering is done.</li>
- * <li>'createdAfter': match all the issues created after the given date (strictly).
- * Both date and datetime ISO formats are supported: 2013-05-18 or 2010-05-18T15:50:45+0100</li>
- * <li>'createdAt': match all the issues created at the given date (require second precision).
- * Both date and datetime ISO formats are supported: 2013-05-18 or 2010-05-18T15:50:45+0100</li>
- * <li>'createdBefore': match all the issues created before the given date (exclusive).
- * Both date and datetime ISO formats are supported: 2013-05-18 or 2010-05-18T15:50:45+0100</li>
- * <li>'pageSize': maximum number of results per page. Default is {@link org.sonar.api.issue.IssueQuery#DEFAULT_PAGE_SIZE},
- * except when the parameter 'components' is set. In this case there's no limit by default (all results in the same page).</li>
- * <li>'pageIndex': index of the selected page. Default is 1.</li>
- * <li>'sort': field to sort on. See supported values in {@link IssueQuery}</li>
- * <li>'asc': ascending or descending sort? Value can be a boolean or strings 'true'/'false'</li>
- * </ul>
- */
- IssueQueryResult find(Map<String, Object> parameters);
-
-}