package org.sonar.core.issue;
import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.issue.Issue;
import org.sonar.core.resource.ResourceDao;
import org.sonar.core.resource.ResourceDto;
-import java.util.Collection;
import java.util.List;
-
-import static com.google.common.collect.Lists.newArrayList;
+import java.util.Map;
+import java.util.Set;
/**
* @since 3.6
this.ruleFinder = ruleFinder;
}
- public List<Issue> find(IssueQuery issueQuery) {
- LOG.debug("IssueQuery : {}", issueQuery);
- Collection<IssueDto> dtoList = issueDao.select(issueQuery);
- return newArrayList(Iterables.transform(dtoList, new Function<IssueDto, Issue>() {
+ public Results find(IssueQuery query) {
+ LOG.debug("IssueQuery : {}", query);
+ List<IssueDto> dtoList = issueDao.select(query);
+
+ final Set<Integer> componentIds = Sets.newLinkedHashSet();
+ final Set<Integer> ruleIds = Sets.newLinkedHashSet();
+ for (IssueDto dto : dtoList) {
+ componentIds.add(dto.getResourceId());
+ ruleIds.add(dto.getRuleId());
+ }
+ final Map<Integer, Rule> rules = Maps.newHashMap();
+ for (Integer ruleId : ruleIds) {
+ Rule rule = ruleFinder.findById(ruleId);
+ if (rule != null) {
+ rules.put(rule.getId(), rule);
+ }
+ }
+ final Map<Integer, ResourceDto> resources = Maps.newHashMap();
+ for (Integer componentId : componentIds) {
+ ResourceDto resource = resourceDao.getResource(componentId);
+ if (resource != null) {
+ resources.put(resource.getId().intValue(), resource);
+ }
+ }
+
+ // TODO verify authorization
+
+ List<Issue> issues = ImmutableList.copyOf(Iterables.transform(dtoList, new Function<IssueDto, Issue>() {
@Override
- public Issue apply(IssueDto input) {
- return toIssue(input);
+ public Issue apply(IssueDto dto) {
+ Rule rule = rules.get(dto.getRuleId());
+ ResourceDto resource = resources.get(dto.getResourceId());
+ return toIssue(dto, rule, resource);
}
}));
+
+
+ return new DefaultResults(issues);
}
- public Issue findByKey(String key){
- IssueDto issueDto = issueDao.findByUuid(key);
- return issueDto != null ? toIssue(issueDto) : null;
+ public Issue findByKey(String key) {
+ IssueDto dto = issueDao.selectByKey(key);
+ Issue issue = null;
+ if (dto != null) {
+ Rule rule = ruleFinder.findById(dto.getRuleId());
+ ResourceDto resource = resourceDao.getResource(dto.getResourceId());
+ issue = toIssue(dto, rule, resource);
+ }
+ return issue;
}
- private Issue toIssue(IssueDto issueDto){
+ private Issue toIssue(IssueDto dto, Rule rule, ResourceDto resource) {
DefaultIssue issue = new DefaultIssue();
- issue.setKey(issueDto.getUuid());
- issue.setStatus(issueDto.getStatus());
- issue.setResolution(issueDto.getResolution());
- issue.setMessage(issueDto.getMessage());
- issue.setTitle(issueDto.getTitle());
- issue.setCost(issueDto.getCost());
- issue.setLine(issueDto.getLine());
- issue.setSeverity(issueDto.getSeverity());
- issue.setUserLogin(issueDto.getUserLogin());
- issue.setAssigneeLogin(issueDto.getAssigneeLogin());
-
- // FIXME
- ResourceDto resource = resourceDao.getResource(issueDto.getResourceId());
- issue.setComponentKey(resource.getKey());
-
- // FIXME
- Rule rule = ruleFinder.findById(issueDto.getRuleId());
- issue.setRuleKey(rule.getKey());
- issue.setRuleRepositoryKey(rule.getRepositoryKey());
-
- issue.setCreatedAt(issueDto.getCreatedAt());
- issue.setUpdatedAt(issueDto.getCreatedAt());
- issue.setClosedAt(issueDto.getUpdatedAt());
-
+ issue.setKey(dto.getUuid());
+ issue.setStatus(dto.getStatus());
+ issue.setResolution(dto.getResolution());
+ issue.setMessage(dto.getMessage());
+ issue.setTitle(dto.getTitle());
+ issue.setCost(dto.getCost());
+ issue.setLine(dto.getLine());
+ issue.setSeverity(dto.getSeverity());
+ issue.setUserLogin(dto.getUserLogin());
+ issue.setAssigneeLogin(dto.getAssigneeLogin());
+ issue.setCreatedAt(dto.getCreatedAt());
+ issue.setUpdatedAt(dto.getCreatedAt());
+ issue.setClosedAt(dto.getUpdatedAt());
+ if (resource != null) {
+ issue.setComponentKey(resource.getKey());
+ }
+ if (rule != null) {
+ issue.setRuleKey(rule.getKey());
+ issue.setRuleRepositoryKey(rule.getRepositoryKey());
+ }
return issue;
}
+ static class DefaultResults implements Results {
+ private final List<Issue> issues;
+
+ DefaultResults(List<Issue> issues) {
+ this.issues = issues;
+ }
+
+ @Override
+ public List<Issue> issues() {
+ return issues;
+ }
+ }
}
package org.sonar.core.issue;
-import com.google.common.base.Preconditions;
+import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
import org.sonar.core.persistence.MyBatis;
import java.util.Collection;
+import java.util.List;
/**
* @since 3.6
public void insert(IssueDto issueDto) {
SqlSession session = mybatis.openSession();
- IssueMapper mapper = session.getMapper(IssueMapper.class);
try {
- mapper.insert(issueDto);
+ // TODO bulk insert
+ session.insert("org.sonar.core.issue.IssueMapper.insert", issueDto);
session.commit();
} finally {
MyBatis.closeQuietly(session);
}
public IssueDao update(Collection<IssueDto> issues) {
- Preconditions.checkNotNull(issues);
-
SqlSession session = mybatis.openBatchSession();
try {
- IssueMapper mapper = session.getMapper(IssueMapper.class);
+ // TODO bulk update
for (IssueDto issue : issues) {
- mapper.update(issue);
+ session.update("org.sonar.core.issue.IssueMapper.update", issue);
}
session.commit();
return this;
}
}
- public IssueDto findById(long issueId) {
+ public IssueDto selectById(long id) {
SqlSession session = mybatis.openSession();
try {
- IssueMapper mapper = session.getMapper(IssueMapper.class);
- return mapper.findById(issueId);
+ return session.selectOne("org.sonar.core.issue.IssueMapper.selectById", id);
} finally {
MyBatis.closeQuietly(session);
}
}
- public IssueDto findByUuid(String uuid) {
+ public IssueDto selectByKey(String key) {
SqlSession session = mybatis.openSession();
try {
- IssueMapper mapper = session.getMapper(IssueMapper.class);
- return mapper.findByUuid(uuid);
+ return session.selectOne("org.sonar.core.issue.IssueMapper.selectByKey", key);
} finally {
MyBatis.closeQuietly(session);
}
}
- public Collection<IssueDto> select(IssueQuery issueQuery) {
+ public List<IssueDto> select(IssueQuery query) {
SqlSession session = mybatis.openSession();
try {
- IssueMapper mapper = session.getMapper(IssueMapper.class);
- return mapper.select(issueQuery);
+ return session.selectList("org.sonar.core.issue.IssueMapper.select", query, new RowBounds(query.offset(), query.limit()));
+
} finally {
MyBatis.closeQuietly(session);
}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-
-package org.sonar.core.issue;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
-import org.sonar.api.ServerComponent;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueFinder;
-import org.sonar.api.issue.IssueQuery;
-
-import java.util.List;
-import java.util.Map;
-
-import static com.google.common.collect.Lists.newArrayList;
-
-/**
- * @since 3.6
- */
-public class IssueFilter implements ServerComponent {
-
- private final IssueFinder issueFinder;
-
- public IssueFilter(IssueFinder issueFinder) {
- this.issueFinder = issueFinder;
- }
-
- public List<Issue> execute(Map<String, String> map) {
- IssueQuery issueQueryBuilder = createIssueQuery(map);
- return issueFinder.find(issueQueryBuilder);
- }
-
- public Issue execute(String key) {
- return !Strings.isNullOrEmpty(key) ? issueFinder.findByKey(key) : null;
- }
-
- @VisibleForTesting
- IssueQuery createIssueQuery(Map<String, String> map) {
- IssueQuery.Builder issueQueryBuilder = new IssueQuery.Builder();
- if (map != null && !map.isEmpty()) {
- if (isPropertyNotEmpty("keys", map)) {
- issueQueryBuilder.keys(getListProperties("keys", map));
- }
- if (isPropertyNotEmpty("severities", map)) {
- issueQueryBuilder.severities(getListProperties("severities", map));
- }
- if (isPropertyNotEmpty("minSeverity", map)) {
- issueQueryBuilder.minSeverity(map.get("minSeverity"));
- }
- if (isPropertyNotEmpty("status", map)) {
- issueQueryBuilder.status(getListProperties("status", map));
- }
- if (isPropertyNotEmpty("resolutions", map)) {
- issueQueryBuilder.resolutions(getListProperties("resolutions", map));
- }
- if (isPropertyNotEmpty("components", map)) {
- issueQueryBuilder.componentKeys(getListProperties("components", map));
- }
- if (isPropertyNotEmpty("rules", map)) {
- issueQueryBuilder.rules(getListProperties("rules", map));
- }
- if (isPropertyNotEmpty("userLogins", map)) {
- issueQueryBuilder.userLogins(getListProperties("userLogins", map));
- }
- if (isPropertyNotEmpty("assigneeLogins", map)) {
- issueQueryBuilder.assigneeLogins(getListProperties("assigneeLogins", map));
- }
- if (isPropertyNotEmpty("limit", map)) {
- issueQueryBuilder.limit(Integer.parseInt(map.get("limit")));
- }
- }
- return issueQueryBuilder.build();
- }
-
- private boolean isPropertyNotEmpty(String property, Map<String, String> map) {
- return map.containsKey(property) && !Strings.isNullOrEmpty(map.get(property));
- }
-
- private List<String> getListProperties(String property, Map<String, String> map) {
- return newArrayList(Splitter.on(',').split(map.get(property)));
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-
-package org.sonar.core.issue;
-
-import org.sonar.api.issue.IssueQuery;
-
-import java.util.Collection;
-
-/**
- * @since 3.6
- */
-public interface IssueMapper {
-
- void insert(IssueDto issueDto);
-
- void update(IssueDto review);
-
- IssueDto findById(long issueId);
-
- IssueDto findByUuid(String uuid);
-
- Collection<IssueDto> select(IssueQuery issueQuery);
-
-}
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.mapping.Environment;
-import org.apache.ibatis.session.*;
+import org.apache.ibatis.session.Configuration;
+import org.apache.ibatis.session.ExecutorType;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.apache.ibatis.type.JdbcType;
import org.slf4j.LoggerFactory;
import org.sonar.api.database.model.MeasureMapper;
import org.sonar.api.database.model.MeasureModel;
import org.sonar.core.config.Logback;
-import org.sonar.core.dashboard.*;
+import org.sonar.core.dashboard.ActiveDashboardDto;
+import org.sonar.core.dashboard.ActiveDashboardMapper;
+import org.sonar.core.dashboard.DashboardDto;
+import org.sonar.core.dashboard.DashboardMapper;
+import org.sonar.core.dashboard.WidgetDto;
+import org.sonar.core.dashboard.WidgetMapper;
+import org.sonar.core.dashboard.WidgetPropertyDto;
+import org.sonar.core.dashboard.WidgetPropertyMapper;
import org.sonar.core.dependency.DependencyDto;
import org.sonar.core.dependency.DependencyMapper;
import org.sonar.core.dependency.ResourceSnapshotDto;
import org.sonar.core.issue.IssueChangeDto;
import org.sonar.core.issue.IssueChangeMapper;
import org.sonar.core.issue.IssueDto;
-import org.sonar.core.issue.IssueMapper;
import org.sonar.core.measure.MeasureFilterDto;
import org.sonar.core.measure.MeasureFilterMapper;
import org.sonar.core.properties.PropertiesMapper;
import org.sonar.core.properties.PropertyDto;
import org.sonar.core.purge.PurgeMapper;
import org.sonar.core.purge.PurgeableSnapshotDto;
-import org.sonar.core.resource.*;
+import org.sonar.core.resource.ResourceDto;
+import org.sonar.core.resource.ResourceIndexDto;
+import org.sonar.core.resource.ResourceIndexerMapper;
+import org.sonar.core.resource.ResourceKeyUpdaterMapper;
+import org.sonar.core.resource.ResourceMapper;
+import org.sonar.core.resource.SnapshotDto;
import org.sonar.core.review.ReviewCommentDto;
import org.sonar.core.review.ReviewCommentMapper;
import org.sonar.core.review.ReviewDto;
import org.sonar.core.source.jdbc.SnapshotSourceMapper;
import org.sonar.core.template.LoadedTemplateDto;
import org.sonar.core.template.LoadedTemplateMapper;
-import org.sonar.core.user.*;
+import org.sonar.core.user.AuthorDto;
+import org.sonar.core.user.AuthorMapper;
+import org.sonar.core.user.GroupDto;
+import org.sonar.core.user.GroupRoleDto;
+import org.sonar.core.user.RoleMapper;
+import org.sonar.core.user.UserDto;
+import org.sonar.core.user.UserMapper;
+import org.sonar.core.user.UserRoleDto;
import java.io.InputStream;
loadAlias(conf, "SnapshotData", SnapshotDataDto.class);
Class<?>[] mappers = {ActiveDashboardMapper.class, AuthorMapper.class, DashboardMapper.class,
- DependencyMapper.class, DuplicationMapper.class, GraphDtoMapper.class, IssueMapper.class, IssueChangeMapper.class, LoadedTemplateMapper.class,
- MeasureFilterMapper.class, PropertiesMapper.class, PurgeMapper.class, ResourceKeyUpdaterMapper.class, ResourceIndexerMapper.class, ResourceMapper.class,
- ResourceSnapshotMapper.class, ReviewCommentMapper.class, ReviewMapper.class, RoleMapper.class, RuleMapper.class, SchemaMigrationMapper.class,
- SemaphoreMapper.class, UserMapper.class, WidgetMapper.class, WidgetPropertyMapper.class, MeasureMapper.class, SnapshotDataMapper.class,
- SnapshotSourceMapper.class
+ DependencyMapper.class, DuplicationMapper.class, GraphDtoMapper.class, IssueChangeMapper.class, LoadedTemplateMapper.class,
+ MeasureFilterMapper.class, PropertiesMapper.class, PurgeMapper.class, ResourceKeyUpdaterMapper.class, ResourceIndexerMapper.class, ResourceMapper.class,
+ ResourceSnapshotMapper.class, ReviewCommentMapper.class, ReviewMapper.class, RoleMapper.class, RuleMapper.class, SchemaMigrationMapper.class,
+ SemaphoreMapper.class, UserMapper.class, WidgetMapper.class, WidgetPropertyMapper.class, MeasureMapper.class, SnapshotDataMapper.class,
+ SnapshotSourceMapper.class
};
loadMappers(conf, mappers);
+ loadMapper(conf, "org.sonar.core.issue.IssueMapper");
configureLogback(mappers);
sessionFactory = new SqlSessionFactoryBuilder().build(conf);
}
private void loadMapper(Configuration configuration, Class mapperClass) {
- String mapperName = mapperClass.getName();
-
- InputStream input = null;
- try {
- input = getClass().getResourceAsStream("/" + mapperName.replace('.', '/') + ".xml");
- new XMLMapperBuilder(input, configuration, mapperName, configuration.getSqlFragments()).parse();
- configuration.addLoadedResource(mapperName);
- } finally {
- Closeables.closeQuietly(input);
- }
+ loadMapper(configuration, mapperClass.getName());
}
+ private void loadMapper(Configuration configuration, String mapperName) {
+ InputStream input = null;
+ try {
+ input = getClass().getResourceAsStream("/" + mapperName.replace('.', '/') + ".xml");
+ new XMLMapperBuilder(input, configuration, mapperName, configuration.getSqlFragments()).parse();
+ configuration.addLoadedResource(mapperName);
+ } finally {
+ Closeables.closeQuietly(input);
+ }
+ }
+
private void loadAlias(Configuration conf, String alias, Class dtoClass) {
conf.getTypeAliasRegistry().registerAlias(alias, dtoClass);
}
where id = #{id}
</update>
- <select id="findById" parameterType="long" resultType="Issue">
+ <select id="selectById" parameterType="long" resultType="Issue">
select <include refid="issueColumns"/>
from issues i
where i.id=#{id}
</select>
- <select id="findByUuid" parameterType="String" resultType="Issue">
+ <select id="selectByKey" parameterType="String" resultType="Issue">
select <include refid="issueColumns"/>
from issues i
where i.uuid=#{uuid}
<select id="select" parameterType="map" resultType="Issue">
select <include refid="issueColumns"/> from issues i
- <if test="componentKeys.size() > 0">
+ <if test="components != null and components.size() > 0">
, projects p, snapshots root, snapshots s
</if>
<where>
- <if test="componentKeys.size() > 0">
+ <if test="components != null and components.size() > 0">
and p.enabled=${_true}
and p.kee in
- <foreach item="componentKey" index="index" collection="componentKeys" open="(" separator="," close=")">#{componentKey}
+ <foreach item="component" index="index" collection="components" open="(" separator="," close=")">
+ #{component}
</foreach>
and root.project_id=p.id
and root.islast=${_true}
<foreach item="severity" index="index" collection="severities" open="(" separator="," close=")">#{severity}
</foreach>
</if>
- <if test="status != null">
+ <if test="statuses != null">
and i.status in
- <foreach item="stat" index="index" collection="status" open="(" separator="," close=")">#{stat}
+ <foreach item="status" index="index" collection="statuses" open="(" separator="," close=")">#{status}
</foreach>
</if>
<if test="resolutions != null">
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
-
package org.sonar.core.issue;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.IssueFinder;
import org.sonar.api.issue.IssueQuery;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.sonar.core.resource.ResourceDao;
import org.sonar.core.resource.ResourceDto;
-import java.util.Collection;
+import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
import static org.fest.assertions.Assertions.assertThat;
public void should_find_issues() {
IssueQuery issueQuery = mock(IssueQuery.class);
- IssueDto issue1 = new IssueDto().setId(1L).setRuleId(1).setResourceId(1);
- IssueDto issue2 = new IssueDto().setId(2L).setRuleId(1).setResourceId(1);
- Collection<IssueDto> dtoList = newArrayList(issue1, issue2);
+ IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setResourceId(123);
+ IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setResourceId(123);
+ List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.select(issueQuery)).thenReturn(dtoList);
- when(ruleFinder.findById(anyInt())).thenReturn(Rule.create("repo", "key"));
- when(resourceDao.getResource(anyInt())).thenReturn(new ResourceDto().setKey("componentKey"));
+ Rule rule = Rule.create("repo", "key");
+ rule.setId(50);
+ when(ruleFinder.findById(anyInt())).thenReturn(rule);
+ when(resourceDao.getResource(anyInt())).thenReturn(new ResourceDto().setKey("componentKey").setId(123L));
- Collection<Issue> issues = finder.find(issueQuery);
- assertThat(issues).hasSize(2);
- Issue issue = issues.iterator().next();
+ IssueFinder.Results results = finder.find(issueQuery);
+ assertThat(results.issues()).hasSize(2);
+ Issue issue = results.issues().iterator().next();
assertThat(issue.componentKey()).isEqualTo("componentKey");
assertThat(issue.ruleKey()).isEqualTo("key");
assertThat(issue.ruleRepositoryKey()).isEqualTo("repo");
@Test
public void should_find_by_key() {
IssueDto issueDto = new IssueDto().setId(1L).setRuleId(1).setResourceId(1);
- when(issueDao.findByUuid("key")).thenReturn(issueDto);
+ when(issueDao.selectByKey("key")).thenReturn(issueDto);
when(ruleFinder.findById(anyInt())).thenReturn(Rule.create("repo", "key"));
when(resourceDao.getResource(anyInt())).thenReturn(new ResourceDto().setKey("componentKey"));
public class IssueDaoTest extends AbstractDaoTestCase {
- private IssueDao dao;
+ IssueDao dao;
@Before
- public void createDao() {
+ public void setUp() {
dao = new IssueDao(getMyBatis());
}
dao.insert(issueDto);
- checkTables("insert", new String[] {"id", "created_at", "updated_at", "closed_at"}, "issues");
+ checkTables("insert", new String[]{"id", "created_at", "updated_at", "closed_at"}, "issues");
}
@Test
public void update() {
setupData("update");
- Collection<IssueDto> issues = newArrayList(dao.findById(100L));
+ Collection<IssueDto> issues = newArrayList(dao.selectById(100L));
IssueDto issue = issues.iterator().next();
issue.setLine(1000);
issue.setResolution("NEW_RESOLUTION");
public void should_find_issue_by_id() {
setupData("shared");
- IssueDto issue = dao.findById(100L);
+ IssueDto issue = dao.selectById(100L);
assertThat(issue.getId()).isEqualTo(100L);
assertThat(issue.getUuid()).isEqualTo("100");
assertThat(issue.getResourceId()).isEqualTo(400);
public void should_find_issue_by_uuid() {
setupData("shared");
- IssueDto issue = dao.findByUuid("100");
+ IssueDto issue = dao.selectByKey("100");
assertThat(issue).isNotNull();
}
public void should_select_by_parameter() {
setupData("select");
- IssueQuery issueQuery = new IssueQuery.Builder().keys(newArrayList("100")).build();
- assertThat(dao.select(issueQuery)).hasSize(1);
+ IssueQuery query = IssueQuery.builder().keys(newArrayList("100")).build();
+ assertThat(dao.select(query)).hasSize(1);
- issueQuery = new IssueQuery.Builder().componentKeys(newArrayList("key")).build();
- assertThat(dao.select(issueQuery)).hasSize(2);
+ query = IssueQuery.builder().components(newArrayList("key")).build();
+ assertThat(dao.select(query)).hasSize(2);
- issueQuery = new IssueQuery.Builder().resolutions(newArrayList("FALSE-POSITIVE")).build();
- assertThat(dao.select(issueQuery)).hasSize(1);
+ query = IssueQuery.builder().resolutions(newArrayList("FALSE-POSITIVE")).build();
+ assertThat(dao.select(query)).hasSize(1);
- issueQuery = new IssueQuery.Builder().status(newArrayList("OPEN")).build();
- assertThat(dao.select(issueQuery)).hasSize(2);
+ query = IssueQuery.builder().statuses(newArrayList("OPEN")).build();
+ assertThat(dao.select(query)).hasSize(2);
- issueQuery = new IssueQuery.Builder().severities(newArrayList("BLOCKER")).build();
- assertThat(dao.select(issueQuery)).hasSize(4);
+ query = IssueQuery.builder().severities(newArrayList("BLOCKER")).build();
+ assertThat(dao.select(query)).hasSize(4);
- issueQuery = new IssueQuery.Builder().userLogins(newArrayList("user")).build();
- assertThat(dao.select(issueQuery)).hasSize(1);
+ query = IssueQuery.builder().userLogins(newArrayList("user")).build();
+ assertThat(dao.select(query)).hasSize(1);
- issueQuery = new IssueQuery.Builder().assigneeLogins(newArrayList("user")).build();
- assertThat(dao.select(issueQuery)).hasSize(5);
+ query = IssueQuery.builder().assigneeLogins(newArrayList("user")).build();
+ assertThat(dao.select(query)).hasSize(5);
- issueQuery = new IssueQuery.Builder().userLogins(newArrayList("user")).status(newArrayList("OPEN")).build();
- assertThat(dao.select(issueQuery)).hasSize(1);
+ query = IssueQuery.builder().userLogins(newArrayList("user")).statuses(newArrayList("OPEN")).build();
+ assertThat(dao.select(query)).hasSize(1);
}
@Test
public void should_return_issues_from_resource_tree() {
setupData("select-with-component-children");
- IssueQuery issueQuery = new IssueQuery.Builder().componentKeys(newArrayList("key")).build();
+ IssueQuery issueQuery = IssueQuery.builder().components(newArrayList("key")).build();
List<IssueDto> issues = newArrayList(dao.select(issueQuery));
assertThat(issues).hasSize(2);
assertThat(issues.get(0).getId()).isEqualTo(100);
public void should_select_without_parameter_return_all_issues() {
setupData("select");
- IssueQuery issueQuery = new IssueQuery.Builder().build();
+ IssueQuery issueQuery = IssueQuery.builder().build();
assertThat(dao.select(issueQuery)).hasSize(5);
}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-
-package org.sonar.core.issue;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueFinder;
-import org.sonar.api.issue.IssueQuery;
-
-import java.util.List;
-import java.util.Map;
-
-import static com.google.common.collect.Maps.newHashMap;
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.*;
-
-public class IssueFilterTest {
-
- private IssueFilter issueFilter;
- private IssueFinder issueFinder;
-
- @Before
- public void before() {
- issueFinder = mock(IssueFinder.class);
- issueFilter = new IssueFilter(issueFinder);
- }
-
- @Test
- public void should_call_find() {
- Map<String, String> map = newHashMap();
- issueFilter.execute(map);
- verify(issueFinder).find(any(IssueQuery.class));
- }
-
- @Test
- public void should_call_find_by_key() {
- issueFilter.execute("key");
- verify(issueFinder).findByKey("key");
- }
-
- @Test
- public void should_not_call_find_by_key_with_empty_key() {
- Issue issue = issueFilter.execute("");
- assertThat(issue).isNull();
- verify(issueFinder, never()).findByKey(anyString());
- }
-
- @Test
- public void should_create_empty_issue_query() {
- Map<String, String> map = newHashMap();
- IssueQuery issueQuery = issueFilter.createIssueQuery(map);
- assertThat(issueQuery.componentKeys()).isEmpty();
- }
-
- @Test
- public void should_create_empty_issue_query_if_value_is_null() {
- Map<String, String> map = newHashMap();
- map.put("components", null);
- IssueQuery issueQuery = issueFilter.createIssueQuery(map);
- assertThat(issueQuery.componentKeys()).isEmpty();
- }
-
- @Test
- public void should_create_issue_query() {
- Map<String, String> map = newHashMap();
- map.put("keys", "keys");
- map.put("severities", "severities");
- map.put("minSeverity", "MINOR");
- map.put("status", "status");
- map.put("resolutions", "resolutions");
- map.put("components", "key");
- map.put("rules", "rules");
- map.put("userLogins", "userLogins");
- map.put("assigneeLogins", "assigneeLogins");
- map.put("limit", "1");
-
- IssueQuery issueQuery = issueFilter.createIssueQuery(map);
- assertThat(issueQuery.keys()).isNotEmpty();
- assertThat(issueQuery.severities()).isNotEmpty();
- assertThat(issueQuery.minSeverity()).isEqualTo("MINOR");
- assertThat(issueQuery.status()).isNotEmpty();
- assertThat(issueQuery.resolutions()).isNotEmpty();
- assertThat(issueQuery.rules()).isNotEmpty();
- assertThat(issueQuery.userLogins()).isNotEmpty();
- assertThat(issueQuery.assigneeLogins()).isNotEmpty();
- assertThat(issueQuery.limit()).isEqualTo(1);
- }
-
- @Test
- public void should_split_property_list() {
- Map<String, String> map = newHashMap();
- map.put("components", "key1,key2");
- IssueQuery issueQuery = issueFilter.createIssueQuery(map);
- List<String> components = issueQuery.componentKeys();
- assertThat(components).hasSize(2);
- assertThat(components).containsOnly("key1", "key2");
- }
-
-}
package org.sonar.api.issue;
import org.sonar.api.ServerComponent;
+import org.sonar.api.component.Component;
+import org.sonar.api.rules.Rule;
+import java.util.Collection;
import java.util.List;
/**
*/
public interface IssueFinder extends ServerComponent {
- List<Issue> find(IssueQuery issueQuery);
+ interface Results {
+ List<Issue> issues();
+ }
+
+ Results find(IssueQuery issueQuery);
Issue findByKey(String key);
package org.sonar.api.issue;
+import com.google.common.base.Preconditions;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import java.util.List;
-
-import static com.google.common.collect.Lists.newArrayList;
+import java.util.Map;
/**
* @since 3.6
*/
public class IssueQuery {
- private List<String> keys;
- private List<String> severities;
- private String minSeverity;
- private List<String> status;
- private List<String> resolutions;
- private List<String> componentKeys;
- private List<String> rules;
- private List<String> userLogins;
- private List<String> assigneeLogins;
- private Integer limit;
+ private final List<String> keys;
+ private final List<String> severities;
+ private final List<String> statuses;
+ private final List<String> resolutions;
+ private final List<String> components;
+ private final List<String> userLogins;
+ private final List<String> assigneeLogins;
+ private final int limit, offset;
private IssueQuery(Builder builder) {
this.keys = builder.keys;
this.severities = builder.severities;
- this.minSeverity = builder.minSeverity;
- this.status = builder.status;
+ this.statuses = builder.statuses;
this.resolutions = builder.resolutions;
- this.componentKeys = builder.componentKeys;
- this.rules = builder.rules;
+ this.components = builder.components;
this.userLogins = builder.userLogins;
this.assigneeLogins = builder.assigneeLogins;
this.limit = builder.limit;
+ this.offset = builder.offset;
}
public List<String> keys() {
return severities;
}
- public String minSeverity() {
- return minSeverity;
- }
-
- public List<String> status() {
- return status;
+ public List<String> statuses() {
+ return statuses;
}
public List<String> resolutions() {
return resolutions;
}
- public List<String> componentKeys() {
- return componentKeys;
- }
-
- public List<String> rules() {
- return rules;
+ public List<String> components() {
+ return components;
}
public List<String> userLogins() {
return assigneeLogins;
}
- public Integer limit() {
+ public int limit() {
return limit;
}
+ public int offset() {
+ return offset;
+ }
+
@Override
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
+ public static Builder builder() {
+ return new Builder();
+ }
+
+
/**
* @since 3.6
*/
public static class Builder {
+ private static final int DEFAULT_LIMIT = 100;
+ private static final int MAX_LIMIT = 5000;
+ private static final int DEFAULT_OFFSET = 0;
+
private List<String> keys;
private List<String> severities;
- private String minSeverity;
- private List<String> status;
+ private List<String> statuses;
private List<String> resolutions;
- private List<String> componentKeys;
- private List<String> rules;
+ private List<String> components;
private List<String> userLogins;
private List<String> assigneeLogins;
- private Integer limit;
-
- public Builder() {
- componentKeys = newArrayList();
- }
+ private int limit = DEFAULT_LIMIT;
+ private int offset = DEFAULT_OFFSET;
- public Builder keys(List<String> keys) {
- this.keys = keys;
- return this;
+ private Builder() {
}
- public Builder severities(List<String> severities) {
- this.severities = severities;
+ public Builder keys(List<String> l) {
+ this.keys = l;
return this;
}
- public Builder minSeverity(String minSeverity) {
- this.minSeverity = minSeverity;
+ public Builder severities(List<String> l) {
+ this.severities = l;
return this;
}
- public Builder status(List<String> status) {
- this.status = status;
+ public Builder statuses(List<String> l) {
+ this.statuses = l;
return this;
}
- public Builder resolutions(List<String> resolutions) {
- this.resolutions = resolutions;
+ public Builder resolutions(List<String> l) {
+ this.resolutions = l;
return this;
}
- public Builder componentKeys(List<String> componentKeys) {
- this.componentKeys = componentKeys;
+ public Builder components(List<String> l) {
+ this.components = l;
return this;
}
- public Builder rules(List<String> rules) {
- this.rules = rules;
+ public Builder userLogins(List<String> l) {
+ this.userLogins = l;
return this;
}
- public Builder userLogins(List<String> userLogins) {
- this.userLogins = userLogins;
+ public Builder assigneeLogins(List<String> l) {
+ this.assigneeLogins = l;
return this;
}
- public Builder assigneeLogins(List<String> assigneeLogins) {
- this.assigneeLogins = assigneeLogins;
+ public Builder limit(Integer i) {
+ Preconditions.checkArgument(i == null || i.intValue() > 0, "Limit must be greater than 0 (got " + i + ")");
+ Preconditions.checkArgument(i == null || i.intValue() < MAX_LIMIT, "Limit must be less than " + MAX_LIMIT + " (got " + i + ")");
+ this.limit = (i == null ? DEFAULT_LIMIT : i.intValue());
return this;
}
- public Builder limit(Integer limit) {
- this.limit = limit;
+ public Builder offset(Integer i) {
+ Preconditions.checkArgument(i == null || i.intValue() >= 0, "Offset must be greater than or equal to 0 (got " + i + ")");
+ this.offset = (i == null ? DEFAULT_OFFSET : i.intValue());
return this;
}
public IssueQuery build() {
return new IssueQuery(this);
}
+ }
- @Override
- public String toString() {
- return ReflectionToStringBuilder.toString(this);
- }
+ public static IssueQuery from(Map<String, Object> props) {
+ IssueQuery.Builder builder = new IssueQuery.Builder();
+ builder.keys((List<String>) props.get("keys"));
+ builder.severities((List<String>) props.get("severities"));
+ builder.statuses((List<String>) props.get("statuses"));
+ builder.resolutions((List<String>) props.get("resolutions"));
+ builder.components((List<String>) props.get("components"));
+ builder.userLogins((List<String>) props.get("userLogins"));
+ builder.assigneeLogins((List<String>) props.get("assigneeLogins"));
+ builder.limit((Integer) props.get("limit"));
+ builder.offset((Integer) props.get("offset"));
+ return builder.build();
}
}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.issue;
+
+import org.junit.Test;
+
+import java.util.Map;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Maps.newHashMap;
+import static org.fest.assertions.Assertions.assertThat;
+
+public class IssueQueryTest {
+ @Test
+ public void should_create_query_from_properties() {
+ Map<String, Object> map = newHashMap();
+ map.put("keys", newArrayList("ABCDE1234"));
+ map.put("severities", newArrayList("MAJOR", "MINOR"));
+ map.put("statuses", newArrayList("CLOSED"));
+ map.put("resolutions", newArrayList("FALSE-POSITIVE"));
+ map.put("components", newArrayList("org.apache"));
+ map.put("userLogins", newArrayList("marilyn"));
+ map.put("assigneeLogins", newArrayList("joanna"));
+ map.put("limit", 10);
+ map.put("offset", 50);
+
+ IssueQuery query = IssueQuery.from(map);
+ assertThat(query.keys()).containsOnly("ABCDE1234");
+ assertThat(query.severities()).containsExactly("MAJOR", "MINOR");
+ assertThat(query.statuses()).containsOnly("CLOSED");
+ assertThat(query.resolutions()).containsOnly("FALSE-POSITIVE");
+ assertThat(query.userLogins()).containsOnly("marilyn");
+ assertThat(query.assigneeLogins()).containsOnly("joanna");
+ assertThat(query.limit()).isEqualTo(10);
+ assertThat(query.offset()).isEqualTo(50);
+ }
+
+
+}
import org.sonar.core.i18n.I18nManager;
import org.sonar.core.i18n.RuleI18nManager;
import org.sonar.core.issue.DefaultIssueFinder;
-import org.sonar.core.issue.IssueFilter;
import org.sonar.core.measure.MeasureFilterEngine;
import org.sonar.core.measure.MeasureFilterExecutor;
import org.sonar.core.measure.MeasureFilterFactory;
import org.sonar.core.metric.DefaultMetricFinder;
import org.sonar.core.notification.DefaultNotificationManager;
-import org.sonar.core.persistence.*;
+import org.sonar.core.persistence.DaoUtils;
+import org.sonar.core.persistence.DatabaseMigrator;
+import org.sonar.core.persistence.DatabaseVersion;
+import org.sonar.core.persistence.DefaultDatabase;
+import org.sonar.core.persistence.DryRunDatabaseFactory;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.persistence.SemaphoreUpdater;
+import org.sonar.core.persistence.SemaphoresImpl;
import org.sonar.core.qualitymodel.DefaultModelFinder;
import org.sonar.core.resource.DefaultResourcePermissions;
import org.sonar.core.rule.DefaultRuleFinder;
import org.sonar.server.notifications.NotificationCenter;
import org.sonar.server.notifications.NotificationService;
import org.sonar.server.notifications.reviews.ReviewsNotificationManager;
-import org.sonar.server.plugins.*;
+import org.sonar.server.plugins.ApplicationDeployer;
+import org.sonar.server.plugins.DefaultServerPluginRepository;
+import org.sonar.server.plugins.InstalledPluginReferentialFactory;
+import org.sonar.server.plugins.PluginDeployer;
+import org.sonar.server.plugins.PluginDownloader;
+import org.sonar.server.plugins.ServerExtensionInstaller;
+import org.sonar.server.plugins.UpdateCenterClient;
+import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.server.qualitymodel.DefaultModelManager;
import org.sonar.server.rules.ProfilesConsole;
import org.sonar.server.rules.RulesConsole;
-import org.sonar.server.startup.*;
-import org.sonar.server.ui.*;
+import org.sonar.server.startup.DeleteDeprecatedMeasures;
+import org.sonar.server.startup.GenerateBootstrapIndex;
+import org.sonar.server.startup.GeneratePluginIndex;
+import org.sonar.server.startup.GwtPublisher;
+import org.sonar.server.startup.JdbcDriverDeployer;
+import org.sonar.server.startup.LogServerId;
+import org.sonar.server.startup.RegisterMetrics;
+import org.sonar.server.startup.RegisterNewDashboards;
+import org.sonar.server.startup.RegisterNewMeasureFilters;
+import org.sonar.server.startup.RegisterNewProfiles;
+import org.sonar.server.startup.RegisterQualityModels;
+import org.sonar.server.startup.RegisterRules;
+import org.sonar.server.startup.RegisterServletFilters;
+import org.sonar.server.startup.RenameDeprecatedPropertyKeys;
+import org.sonar.server.startup.ServerMetadataPersister;
+import org.sonar.server.ui.CodeColorizers;
+import org.sonar.server.ui.JRubyI18n;
+import org.sonar.server.ui.PageDecorations;
+import org.sonar.server.ui.SecurityRealmFactory;
+import org.sonar.server.ui.Views;
import javax.servlet.ServletContext;
servicesContainer.addSingleton(DefaultResourcePermissions.class);
servicesContainer.addSingleton(Periods.class);
servicesContainer.addSingleton(DefaultIssueFinder.class);
- servicesContainer.addSingleton(IssueFilter.class);
// Notifications
servicesContainer.addSingleton(EmailSettings.class);
import org.sonar.api.workflow.screen.Screen;
import org.sonar.core.component.SnapshotPerspectives;
import org.sonar.core.i18n.RuleI18nManager;
-import org.sonar.core.issue.IssueFilter;
import org.sonar.core.measure.MeasureFilterEngine;
import org.sonar.core.measure.MeasureFilterResult;
import org.sonar.core.persistence.Database;
return get(SyntaxHighlighter.class).getHighlightedSourceAsHtml(snapshotId);
}
- public IssueFilter getIssueFilter() {
- return get(IssueFilter.class);
- }
+// public IssueFilter getIssueFilter() {
+// return get(IssueFilter.class);
+// }
}