summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2014-05-20 15:55:34 +0200
committerJulien Lancelot <julien.lancelot@sonarsource.com>2014-05-20 16:21:10 +0200
commit28d2cf2e08e4d8dd42904e8fc1db92e50905e54b (patch)
tree19dec5638bb87720ae45522ebbed1d5cad4cb659
parente490ee5188bc25eab1cd03fbd9f2df55301db370 (diff)
downloadsonarqube-28d2cf2e08e4d8dd42904e8fc1db92e50905e54b.tar.gz
sonarqube-28d2cf2e08e4d8dd42904e8fc1db92e50905e54b.zip
SONAR-5305 Do only one SQL to retun all measures
-rw-r--r--sonar-core/src/main/java/org/sonar/api/package-info.java (renamed from sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDao.java)27
-rw-r--r--sonar-core/src/main/java/org/sonar/core/cluster/package-info.java24
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java25
-rw-r--r--sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDto.java31
-rw-r--r--sonar-core/src/main/java/org/sonar/core/measure/db/MeasureKey.java79
-rw-r--r--sonar-core/src/main/java/org/sonar/core/measure/db/MeasureMapper.java6
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java16
-rw-r--r--sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java13
-rw-r--r--sonar-core/src/main/java/org/sonar/core/resource/ResourceDao.java33
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/measure/db/MeasureMapper.xml24
-rw-r--r--sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java14
-rw-r--r--sonar-core/src/test/java/org/sonar/core/measure/db/MeasureDaoTest.java69
-rw-r--r--sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java8
-rw-r--r--sonar-core/src/test/java/org/sonar/core/resource/ResourceDaoTest.java22
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java13
-rw-r--r--sonar-server/src/main/java/org/sonar/server/cluster/LocalNonBlockingWorkQueue.java4
-rw-r--r--sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java152
-rw-r--r--sonar-server/src/main/java/org/sonar/server/db/BaseDao.java48
-rw-r--r--sonar-server/src/main/java/org/sonar/server/issue/IssueService.java9
-rw-r--r--sonar-server/src/main/java/org/sonar/server/measure/persistence/MeasureDao.java86
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java14
-rw-r--r--sonar-server/src/main/java/org/sonar/server/source/SourceService.java23
-rw-r--r--sonar-server/src/main/java/org/sonar/server/test/CoverageService.java22
-rw-r--r--sonar-server/src/main/java/org/sonar/server/user/UserSession.java22
-rw-r--r--sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java65
-rw-r--r--sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java7
-rw-r--r--sonar-server/src/test/java/org/sonar/server/issue/IssueServiceTest.java29
-rw-r--r--sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java96
-rw-r--r--sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesMediumTest.java3
-rw-r--r--sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java26
-rw-r--r--sonar-server/src/test/java/org/sonar/server/test/CoverageServiceTest.java36
-rw-r--r--sonar-server/src/test/java/org/sonar/server/user/MockUserSession.java7
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/measure/persistence/MeasureDaoTest/shared.xml (renamed from sonar-core/src/test/resources/org/sonar/core/measure/db/MeasureDaoTest/shared.xml)0
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/package-info.java24
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/source/package-info.java24
35 files changed, 751 insertions, 350 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDao.java b/sonar-core/src/main/java/org/sonar/api/package-info.java
index c8a3e92ca88..8e7e23ac52d 100644
--- a/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDao.java
+++ b/sonar-core/src/main/java/org/sonar/api/package-info.java
@@ -18,28 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.core.measure.db;
+@ParametersAreNonnullByDefault
+package org.sonar.api;
-import org.apache.ibatis.session.SqlSession;
-import org.sonar.api.ServerComponent;
-import org.sonar.core.persistence.MyBatis;
-
-public class MeasureDao implements ServerComponent {
-
- private MyBatis mybatis;
-
- public MeasureDao(MyBatis mybatis) {
- this.mybatis = mybatis;
- }
-
- public MeasureDto findByComponentKeyAndMetricKey(String componentKey, String metricKey) {
- SqlSession session = mybatis.openSession(false);
- try {
- MeasureMapper mapper = session.getMapper(MeasureMapper.class);
- return mapper.findByComponentKeyAndMetricKey(componentKey, metricKey);
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
-}
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-core/src/main/java/org/sonar/core/cluster/package-info.java b/sonar-core/src/main/java/org/sonar/core/cluster/package-info.java
new file mode 100644
index 00000000000..404b0c30ca4
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/cluster/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.core.cluster;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java
index 44bfdb9de51..3aad9a41f25 100644
--- a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java
+++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java
@@ -27,6 +27,7 @@ import org.apache.ibatis.session.SqlSession;
import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
import org.sonar.api.issue.IssueQuery;
+import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.rule.RuleDto;
@@ -94,11 +95,11 @@ public class IssueDao implements BatchComponent, ServerComponent {
/**
* The returned IssueDto list contains only the issue id and the sort column
*/
- public List<IssueDto> selectIssueIds(IssueQuery query, @Nullable Integer userId, SqlSession session){
+ public List<IssueDto> selectIssueIds(IssueQuery query, @Nullable Integer userId, SqlSession session) {
return selectIssueIds(query, userId, query.maxResults(), session);
}
- private List<IssueDto> selectIssueIds(IssueQuery query, @Nullable Integer userId, Integer maxResults, SqlSession session){
+ private List<IssueDto> selectIssueIds(IssueQuery query, @Nullable Integer userId, Integer maxResults, SqlSession session) {
IssueMapper mapper = session.getMapper(IssueMapper.class);
return mapper.selectIssueIds(query, query.componentRoots(), userId, query.requiredRole(), maxResults);
}
@@ -112,7 +113,7 @@ public class IssueDao implements BatchComponent, ServerComponent {
}
}
- public List<IssueDto> selectIssues(IssueQuery query, @Nullable Integer userId, SqlSession session){
+ public List<IssueDto> selectIssues(IssueQuery query, @Nullable Integer userId, SqlSession session) {
IssueMapper mapper = session.getMapper(IssueMapper.class);
return mapper.selectIssues(query, query.componentRoots(), userId, query.requiredRole());
}
@@ -141,22 +142,12 @@ public class IssueDao implements BatchComponent, ServerComponent {
}
// TODO replace by aggregation in IssueIndex
- public List<RuleDto> findRulesByComponent(String componentKey) {
- SqlSession session = mybatis.openSession(false);
- try {
- return session.getMapper(IssueMapper.class).findRulesByComponent(componentKey);
- } finally {
- MyBatis.closeQuietly(session);
- }
+ public List<RuleDto> findRulesByComponent(String componentKey, DbSession session) {
+ return session.getMapper(IssueMapper.class).findRulesByComponent(componentKey);
}
// TODO replace by aggregation in IssueIndex
- public List<String> findSeveritiesByComponent(String componentKey) {
- SqlSession session = mybatis.openSession(false);
- try {
- return session.getMapper(IssueMapper.class).findSeveritiesByComponent(componentKey);
- } finally {
- MyBatis.closeQuietly(session);
- }
+ public List<String> findSeveritiesByComponent(String componentKey, DbSession session) {
+ return session.getMapper(IssueMapper.class).findSeveritiesByComponent(componentKey);
}
}
diff --git a/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDto.java b/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDto.java
index edbfe96b28a..886a06d31ee 100644
--- a/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDto.java
+++ b/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDto.java
@@ -21,15 +21,18 @@
package org.sonar.core.measure.db;
import com.google.common.base.Charsets;
+import org.sonar.core.persistence.Dto;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-public class MeasureDto {
+public class MeasureDto extends Dto<MeasureKey>{
private Integer id;
- private Integer snapshotId;
+ private String metricKey;
+
+ private String componentKey;
private Double value;
@@ -37,6 +40,10 @@ public class MeasureDto {
private byte[] data;
+ private MeasureDto(){
+ // Nothing here
+ }
+
public Integer getId() {
return id;
}
@@ -46,12 +53,13 @@ public class MeasureDto {
return this;
}
- public Integer getSnapshotId() {
- return snapshotId;
+ private MeasureDto setMetricKey(String metricKey) {
+ this.metricKey = metricKey;
+ return this;
}
- public MeasureDto setSnapshotId(Integer snapshotId) {
- this.snapshotId = snapshotId;
+ private MeasureDto setComponentKey(String componentKey) {
+ this.componentKey = componentKey;
return this;
}
@@ -83,4 +91,15 @@ public class MeasureDto {
}
return textValue;
}
+
+ @Override
+ public MeasureKey getKey() {
+ return MeasureKey.of(componentKey, metricKey);
+ }
+
+ public static MeasureDto createFor(MeasureKey key){
+ return new MeasureDto()
+ .setComponentKey(key.componentKey())
+ .setMetricKey(key.metricKey());
+ }
}
diff --git a/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureKey.java b/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureKey.java
new file mode 100644
index 00000000000..2945d9845b3
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureKey.java
@@ -0,0 +1,79 @@
+/*
+ * 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.measure.db;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
+import java.io.Serializable;
+
+public class MeasureKey implements Serializable {
+
+ private final String componentKey;
+ private final String metricKey;
+
+ private MeasureKey(String componentKey, String metricKey) {
+ this.componentKey = componentKey;
+ this.metricKey = metricKey;
+ }
+
+ public String componentKey() {
+ return componentKey;
+ }
+
+ public String metricKey() {
+ return metricKey;
+ }
+
+ public static MeasureKey of(String componentKey, String metricKey) {
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(componentKey), "Component key must be set");
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(metricKey), "Metric key must be set");
+ return new MeasureKey(componentKey, metricKey);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ MeasureKey that = (MeasureKey) o;
+
+ if (!componentKey.equals(that.componentKey)) {
+ return false;
+ }
+ if (!metricKey.equals(that.metricKey)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = componentKey.hashCode();
+ result = 31 * result + metricKey.hashCode();
+ return result;
+ }
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureMapper.java b/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureMapper.java
index fd27c9b1d82..fc3db6097b4 100644
--- a/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureMapper.java
+++ b/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureMapper.java
@@ -22,8 +22,12 @@ package org.sonar.core.measure.db;
import org.apache.ibatis.annotations.Param;
+import java.util.List;
+
public interface MeasureMapper {
- MeasureDto findByComponentKeyAndMetricKey(@Param("componentKey") String componentKey, @Param("metricKey") String metricKey);
+ MeasureDto selectByKey(@Param("key") MeasureKey key);
+
+ List<MeasureDto> selectByComponentAndMetrics(@Param("componentKey") String componentKey, @Param("metricKeys") List<String> metricKeys);
}
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java b/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java
index 771c8134ef6..7d5247d3fe3 100644
--- a/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java
@@ -24,14 +24,7 @@ import org.sonar.core.dashboard.ActiveDashboardDao;
import org.sonar.core.dashboard.DashboardDao;
import org.sonar.core.duplication.DuplicationDao;
import org.sonar.core.graph.jdbc.GraphDao;
-import org.sonar.core.issue.db.ActionPlanDao;
-import org.sonar.core.issue.db.ActionPlanStatsDao;
-import org.sonar.core.issue.db.IssueChangeDao;
-import org.sonar.core.issue.db.IssueDao;
-import org.sonar.core.issue.db.IssueFilterDao;
-import org.sonar.core.issue.db.IssueFilterFavouriteDao;
-import org.sonar.core.issue.db.IssueStatsDao;
-import org.sonar.core.measure.db.MeasureDao;
+import org.sonar.core.issue.db.*;
import org.sonar.core.notification.db.NotificationQueueDao;
import org.sonar.core.permission.PermissionDao;
import org.sonar.core.permission.PermissionTemplateDao;
@@ -48,11 +41,7 @@ import org.sonar.core.source.db.SnapshotSourceDao;
import org.sonar.core.technicaldebt.db.CharacteristicDao;
import org.sonar.core.technicaldebt.db.RequirementDao;
import org.sonar.core.template.LoadedTemplateDao;
-import org.sonar.core.user.AuthorDao;
-import org.sonar.core.user.AuthorizationDao;
-import org.sonar.core.user.GroupMembershipDao;
-import org.sonar.core.user.RoleDao;
-import org.sonar.core.user.UserDao;
+import org.sonar.core.user.*;
import java.util.List;
@@ -81,7 +70,6 @@ public final class DaoUtils {
IssueFilterDao.class,
IssueFilterFavouriteDao.class,
LoadedTemplateDao.class,
- MeasureDao.class,
NotificationQueueDao.class,
PermissionDao.class,
PermissionTemplateDao.class,
diff --git a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java
index 5ac44bf1c4e..785416c5bad 100644
--- a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java
+++ b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java
@@ -24,6 +24,7 @@ import com.google.common.base.Strings;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.session.SqlSession;
import org.sonar.api.BatchComponent;
+import org.sonar.api.DaoComponent;
import org.sonar.api.ServerComponent;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
@@ -33,7 +34,7 @@ import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
-public class PropertiesDao implements BatchComponent, ServerComponent {
+public class PropertiesDao implements BatchComponent, ServerComponent, DaoComponent {
private static final String NOTIFICATION_PREFIX = "notification.";
private MyBatis mybatis;
@@ -111,14 +112,8 @@ public class PropertiesDao implements BatchComponent, ServerComponent {
}
}
- public List<PropertyDto> selectByQuery(PropertyQuery query) {
- SqlSession session = mybatis.openSession(false);
- PropertiesMapper mapper = session.getMapper(PropertiesMapper.class);
- try {
- return mapper.selectByQuery(query);
- } finally {
- MyBatis.closeQuietly(session);
- }
+ public List<PropertyDto> selectByQuery(PropertyQuery query, DbSession session) {
+ return session.getMapper(PropertiesMapper.class).selectByQuery(query);
}
public void setProperty(PropertyDto property, SqlSession session) {
diff --git a/sonar-core/src/main/java/org/sonar/core/resource/ResourceDao.java b/sonar-core/src/main/java/org/sonar/core/resource/ResourceDao.java
index 3d6ac2c7deb..80059b30e91 100644
--- a/sonar-core/src/main/java/org/sonar/core/resource/ResourceDao.java
+++ b/sonar-core/src/main/java/org/sonar/core/resource/ResourceDao.java
@@ -23,8 +23,10 @@ import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.apache.ibatis.session.SqlSession;
+import org.sonar.api.DaoComponent;
import org.sonar.api.component.Component;
import org.sonar.core.component.ComponentDto;
+import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import javax.annotation.CheckForNull;
@@ -37,7 +39,7 @@ import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
-public class ResourceDao {
+public class ResourceDao implements DaoComponent {
private MyBatis mybatis;
public ResourceDao(MyBatis mybatis) {
@@ -108,16 +110,6 @@ public class ResourceDao {
}
@CheckForNull
- public SnapshotDto getLastSnapshotByResourceId(long resourceId) {
- SqlSession session = mybatis.openSession(false);
- try {
- return getLastSnapshotByResourceId(resourceId, session);
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
- @CheckForNull
public SnapshotDto getLastSnapshotByResourceId(long resourceId, SqlSession session) {
return session.getMapper(ResourceMapper.class).selectLastSnapshotByResourceId(resourceId);
}
@@ -184,13 +176,8 @@ public class ResourceDao {
}
@CheckForNull
- public ComponentDto selectComponentByKey(String key) {
- SqlSession session = mybatis.openSession(false);
- try {
- return session.getMapper(ResourceMapper.class).selectComponentByKey(key);
- } finally {
- MyBatis.closeQuietly(session);
- }
+ public ComponentDto selectComponentByKey(String key, DbSession session) {
+ return session.getMapper(ResourceMapper.class).selectComponentByKey(key);
}
@CheckForNull
@@ -200,16 +187,6 @@ public class ResourceDao {
}
@CheckForNull
- public Component findById(Long id) {
- SqlSession session = mybatis.openSession(false);
- try {
- return findById(id, session);
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
- @CheckForNull
public Component findById(Long id, SqlSession session) {
ResourceDto resourceDto = getResource(id, session);
return resourceDto != null ? toComponent(resourceDto) : null;
diff --git a/sonar-core/src/main/resources/org/sonar/core/measure/db/MeasureMapper.xml b/sonar-core/src/main/resources/org/sonar/core/measure/db/MeasureMapper.xml
index e4770360adb..e7553613f56 100644
--- a/sonar-core/src/main/resources/org/sonar/core/measure/db/MeasureMapper.xml
+++ b/sonar-core/src/main/resources/org/sonar/core/measure/db/MeasureMapper.xml
@@ -8,19 +8,37 @@
pm.snapshot_id as snapshotId,
pm.value as value,
pm.text_value as textValue,
- pm.measure_data as data
+ pm.measure_data as data,
+ p.kee as componentKey,
+ metric.name as metricKey
</sql>
- <select id="findByComponentKeyAndMetricKey" parameterType="map" resultType="Measure">
+ <select id="selectByKey" parameterType="map" resultType="Measure">
SELECT
<include refid="measureColumns"/>
FROM project_measures pm
INNER JOIN snapshots s ON s.id=pm.snapshot_id AND s.islast=${_true}
+ INNER JOIN metrics metric ON metric.id=pm.metric_id
+ INNER JOIN projects p ON p.id=s.project_id AND p.enabled=${_true}
+ <where>
+ AND p.kee = #{key.componentKey}
+ AND metric.name = #{key.metricKey}
+ AND pm.rule_id IS NULL
+ AND pm.characteristic_id IS NULL
+ AND pm.person_id IS NULL
+ </where>
+ </select>
+
+ <select id="selectByComponentAndMetrics" parameterType="map" resultType="Measure">
+ SELECT metric.name as metric_name,
+ <include refid="measureColumns"/>
+ FROM project_measures pm
+ INNER JOIN snapshots s ON s.id=pm.snapshot_id AND s.islast=${_true}
INNER JOIN projects p ON p.id=s.project_id AND p.enabled=${_true}
INNER JOIN metrics metric ON metric.id=pm.metric_id
<where>
AND p.kee = #{componentKey}
- AND metric.name = #{metricKey}
+ AND <foreach item="metricKey" index="index" collection="metricKeys" open="(" separator=" or " close=")">metric.name=#{metricKey}</foreach>
AND pm.rule_id IS NULL
AND pm.characteristic_id IS NULL
AND pm.person_id IS NULL
diff --git a/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java b/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java
index cf8dc4a3d3b..4f2f0e2c528 100644
--- a/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java
@@ -23,6 +23,7 @@ package org.sonar.core.issue.db;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import org.apache.ibatis.executor.result.DefaultResultHandler;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.issue.IssueQuery;
@@ -30,6 +31,7 @@ import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.DateUtils;
import org.sonar.core.persistence.AbstractDaoTestCase;
+import org.sonar.core.persistence.DbSession;
import org.sonar.core.rule.RuleDto;
import java.util.List;
@@ -40,13 +42,21 @@ import static org.fest.assertions.Assertions.assertThat;
public class IssueDaoTest extends AbstractDaoTestCase {
+ DbSession session;
+
IssueDao dao;
@Before
public void createDao() {
+ session = getMyBatis().openSession(false);
dao = new IssueDao(getMyBatis());
}
+ @After
+ public void tearDown() throws Exception {
+ session.close();
+ }
+
@Test
public void should_select_by_key() {
setupData("shared", "should_select_by_key");
@@ -434,7 +444,7 @@ public class IssueDaoTest extends AbstractDaoTestCase {
public void find_rules_by_component() {
setupData("shared", "find_rules_by_component");
- List<RuleDto> results = dao.findRulesByComponent("Action.java");
+ List<RuleDto> results = dao.findRulesByComponent("Action.java", session);
assertThat(results).hasSize(3);
}
@@ -442,7 +452,7 @@ public class IssueDaoTest extends AbstractDaoTestCase {
public void find_severities_by_component() {
setupData("shared", "find_severities_by_component");
- List<String> results = dao.findSeveritiesByComponent("Action.java");
+ List<String> results = dao.findSeveritiesByComponent("Action.java", session);
assertThat(results).containsExactly(Severity.BLOCKER, Severity.MAJOR, Severity.BLOCKER);
}
diff --git a/sonar-core/src/test/java/org/sonar/core/measure/db/MeasureDaoTest.java b/sonar-core/src/test/java/org/sonar/core/measure/db/MeasureDaoTest.java
deleted file mode 100644
index e00ccc5cdf9..00000000000
--- a/sonar-core/src/test/java/org/sonar/core/measure/db/MeasureDaoTest.java
+++ /dev/null
@@ -1,69 +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.measure.db;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.core.persistence.AbstractDaoTestCase;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class MeasureDaoTest extends AbstractDaoTestCase {
-
- private MeasureDao dao;
-
- @Before
- public void createDao() {
- dao = new MeasureDao(getMyBatis());
- }
-
- @Test
- public void find_value_by_component_key_and_metric_key() throws Exception {
- setupData("shared");
-
- MeasureDto result = dao.findByComponentKeyAndMetricKey("org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc");
- assertThat(result.getId()).isEqualTo(22);
- assertThat(result.getSnapshotId()).isEqualTo(5);
- assertThat(result.getValue()).isEqualTo(10d);
- }
-
- @Test
- public void find_data_by_component_key_and_metric_key() throws Exception {
- setupData("shared");
-
- MeasureDto result = dao.findByComponentKeyAndMetricKey("org.struts:struts-core:src/org/struts/RequestContext.java", "authors_by_line");
- assertThat(result.getId()).isEqualTo(20);
- assertThat(result.getSnapshotId()).isEqualTo(5);
- assertThat(result.getData()).isNotNull();
-
- assertThat(result.getData()).isEqualTo("0123456789012345678901234567890123456789");
- }
-
- @Test
- public void find_text_value_by_component_key_and_metric_key() throws Exception {
- setupData("shared");
-
- MeasureDto result = dao.findByComponentKeyAndMetricKey("org.struts:struts-core:src/org/struts/RequestContext.java", "coverage_line_hits_data");
- assertThat(result.getId()).isEqualTo(21);
- assertThat(result.getSnapshotId()).isEqualTo(5);
- assertThat(result.getData()).isEqualTo("36=1;37=1;38=1;39=1;43=1;48=1;53=1");
- }
-}
diff --git a/sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java b/sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java
index 9e902a97357..ce832311193 100644
--- a/sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java
@@ -25,6 +25,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.core.persistence.AbstractDaoTestCase;
+import org.sonar.core.persistence.DbSession;
import java.util.List;
@@ -34,6 +35,8 @@ import static org.junit.Assert.assertThat;
public class PropertiesDaoTest extends AbstractDaoTestCase {
+ private DbSession session;
+
private PropertiesDao dao;
@Rule
@@ -42,6 +45,7 @@ public class PropertiesDaoTest extends AbstractDaoTestCase {
@Before
public void createDao() {
dao = new PropertiesDao(getMyBatis());
+ session = getMyBatis().openSession(false);
}
@Test
@@ -146,11 +150,11 @@ public class PropertiesDaoTest extends AbstractDaoTestCase {
public void select_by_query() {
setupData("select_by_query");
- List<PropertyDto> results = dao.selectByQuery(PropertyQuery.builder().setKey("user.two").setComponentId(10L).setUserId(100).build());
+ List<PropertyDto> results = dao.selectByQuery(PropertyQuery.builder().setKey("user.two").setComponentId(10L).setUserId(100).build(), session);
assertThat(results).hasSize(1);
assertThat(results.get(0).getValue()).isEqualTo("two");
- results = dao.selectByQuery(PropertyQuery.builder().setKey("user.one").setUserId(100).build());
+ results = dao.selectByQuery(PropertyQuery.builder().setKey("user.one").setUserId(100).build(), session);
assertThat(results).hasSize(1);
assertThat(results.get(0).getValue()).isEqualTo("one");
}
diff --git a/sonar-core/src/test/java/org/sonar/core/resource/ResourceDaoTest.java b/sonar-core/src/test/java/org/sonar/core/resource/ResourceDaoTest.java
index c40a43ea280..fe284fbc8d8 100644
--- a/sonar-core/src/test/java/org/sonar/core/resource/ResourceDaoTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/resource/ResourceDaoTest.java
@@ -29,6 +29,7 @@ import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.persistence.AbstractDaoTestCase;
+import org.sonar.core.persistence.DbSession;
import javax.annotation.Nullable;
@@ -41,10 +42,13 @@ import static org.fest.assertions.Assertions.assertThat;
public class ResourceDaoTest extends AbstractDaoTestCase {
+ private DbSession session;
+
private ResourceDao dao;
@Before
public void createDao() {
+ session = getMyBatis().openSession(false);
dao = new ResourceDao(getMyBatis());
}
@@ -213,8 +217,8 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
public void select_component_by_key() {
setupData("fixture");
- assertThat(dao.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext.java")).isNotNull();
- assertThat(dao.selectComponentByKey("unknown")).isNull();
+ assertThat(dao.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext.java", session)).isNotNull();
+ assertThat(dao.selectComponentByKey("unknown", session)).isNull();
}
@Test
@@ -377,9 +381,9 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
public void should_find_component_by_id() {
setupData("fixture");
- assertThat(dao.findById(1L)).isNotNull();
- assertThat(dao.findById(4L)).isNotNull();
- assertThat(dao.findById(555L)).isNull();
+ assertThat(dao.findById(1L, session)).isNotNull();
+ assertThat(dao.findById(4L, session)).isNotNull();
+ assertThat(dao.findById(555L, session)).isNull();
}
@Test
@@ -443,16 +447,16 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
public void get_last_snapshot_by_resource_id() {
setupData("fixture");
- SnapshotDto snapshotDto = dao.getLastSnapshotByResourceId(1L);
+ SnapshotDto snapshotDto = dao.getLastSnapshotByResourceId(1L, session);
assertThat(snapshotDto.getId()).isEqualTo(1);
- snapshotDto = dao.getLastSnapshotByResourceId(2L);
+ snapshotDto = dao.getLastSnapshotByResourceId(2L, session);
assertThat(snapshotDto.getId()).isEqualTo(2L);
- snapshotDto = dao.getLastSnapshotByResourceId(3L);
+ snapshotDto = dao.getLastSnapshotByResourceId(3L, session);
assertThat(snapshotDto.getId()).isEqualTo(3L);
- assertThat(dao.getLastSnapshotByResourceId(42L)).isNull();
+ assertThat(dao.getLastSnapshotByResourceId(42L, session)).isNull();
}
private List<String> getKeys(final List<Component> components) {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
index 6399bff81b3..97571eb20ad 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
@@ -20,10 +20,14 @@
package org.sonar.api.measures;
import com.google.common.annotations.Beta;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.sonar.api.resources.Scopes;
import org.sonar.api.utils.SonarException;
+import javax.annotation.Nullable;
+
import java.lang.reflect.Field;
import java.util.List;
@@ -2286,4 +2290,13 @@ public final class CoreMetrics {
public static List<Metric> getMetrics() {
return METRICS;
}
+
+ public static Metric getMetric(final String key) {
+ return Iterables.find(METRICS, new Predicate<Metric>() {
+ @Override
+ public boolean apply(@Nullable Metric input) {
+ return input != null && input.getKey().equals(key);
+ }
+ });
+ }
}
diff --git a/sonar-server/src/main/java/org/sonar/server/cluster/LocalNonBlockingWorkQueue.java b/sonar-server/src/main/java/org/sonar/server/cluster/LocalNonBlockingWorkQueue.java
index 786d1648bc4..cfa1d0bf6c8 100644
--- a/sonar-server/src/main/java/org/sonar/server/cluster/LocalNonBlockingWorkQueue.java
+++ b/sonar-server/src/main/java/org/sonar/server/cluster/LocalNonBlockingWorkQueue.java
@@ -44,7 +44,7 @@ public class LocalNonBlockingWorkQueue extends LinkedBlockingQueue<Runnable>
this.offer(action, 1000, TimeUnit.SECONDS);
latch.await(1500, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
- throw new IllegalStateException("ES update has been interrupted: ");
+ throw new IllegalStateException("ES update has been interrupted", e);
}
}
@@ -58,7 +58,7 @@ public class LocalNonBlockingWorkQueue extends LinkedBlockingQueue<Runnable>
}
latch.await(1500, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
- throw new IllegalStateException("ES update has been interrupted: ");
+ throw new IllegalStateException("ES update has been interrupted", e);
}
}
}
diff --git a/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java b/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java
index 2535694121c..e632b6eef4b 100644
--- a/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java
+++ b/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java
@@ -20,6 +20,8 @@
package org.sonar.server.component.ws;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Multiset;
import com.google.common.io.Resources;
import org.sonar.api.component.Component;
@@ -35,17 +37,20 @@ import org.sonar.api.utils.Durations;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.ComponentDto;
-import org.sonar.core.measure.db.MeasureDao;
import org.sonar.core.measure.db.MeasureDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
import org.sonar.core.properties.PropertiesDao;
import org.sonar.core.properties.PropertyDto;
import org.sonar.core.properties.PropertyQuery;
import org.sonar.core.resource.ResourceDao;
import org.sonar.core.resource.SnapshotDto;
import org.sonar.core.timemachine.Periods;
+import org.sonar.server.db.DbClient;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.issue.IssueService;
import org.sonar.server.issue.RulesAggregation;
+import org.sonar.server.measure.persistence.MeasureDao;
import org.sonar.server.user.UserSession;
import javax.annotation.CheckForNull;
@@ -54,22 +59,27 @@ import javax.annotation.Nullable;
import java.util.Date;
import java.util.List;
+import static com.google.common.collect.Lists.newArrayList;
+
public class ComponentAppAction implements RequestHandler {
private static final String KEY = "key";
+ private final DbClient dbClient;
+
private final ResourceDao resourceDao;
- private final MeasureDao measureDao;
private final PropertiesDao propertiesDao;
+ private final MeasureDao measureDao;
private final IssueService issueService;
private final Periods periods;
private final Durations durations;
private final I18n i18n;
- public ComponentAppAction(ResourceDao resourceDao, MeasureDao measureDao, PropertiesDao propertiesDao, IssueService issueService, Periods periods, Durations durations, I18n i18n) {
- this.resourceDao = resourceDao;
- this.measureDao = measureDao;
- this.propertiesDao = propertiesDao;
+ public ComponentAppAction(DbClient dbClient, IssueService issueService, Periods periods, Durations durations, I18n i18n) {
+ this.dbClient = dbClient;
+ this.resourceDao = dbClient.getDao(ResourceDao.class);
+ this.propertiesDao = dbClient.getDao(PropertiesDao.class);
+ this.measureDao = dbClient.getDao(MeasureDao.class);
this.issueService = issueService;
this.periods = periods;
this.durations = durations;
@@ -100,59 +110,74 @@ public class ComponentAppAction implements RequestHandler {
JsonWriter json = response.newJsonWriter();
json.beginObject();
- ComponentDto component = resourceDao.selectComponentByKey(fileKey);
- if (component == null) {
- throw new NotFoundException(String.format("Component '%s' does not exists.", fileKey));
- }
- Long projectId = component.projectId();
- Long subProjectId = component.subProjectId();
- // projectId and subProjectId can't be null here
- if (projectId != null && subProjectId != null) {
- List<PropertyDto> propertyDtos = propertiesDao.selectByQuery(PropertyQuery.builder()
- .setKey("favourite")
- .setComponentId(component.getId())
- .setUserId(userSession.userId())
- .build());
- boolean isFavourite = propertyDtos.size() == 1;
-
- json.prop("key", component.key());
- json.prop("path", component.path());
- json.prop("name", component.name());
- json.prop("q", component.qualifier());
-
- Component subProject = componentById(subProjectId);
- json.prop("subProjectName", subProject != null ? subProject.longName() : null);
-
- Component project = componentById(projectId);
- json.prop("projectName", project != null ? project.longName() : null);
-
- json.prop("fav", isFavourite);
- appendPeriods(json, projectId);
- appendRulesAggregation(json, component.key());
- appendMeasures(json, fileKey);
+ DbSession session = dbClient.openSession(false);
+ try {
+ ComponentDto component = resourceDao.selectComponentByKey(fileKey, session);
+ if (component == null) {
+ throw new NotFoundException(String.format("Component '%s' does not exists.", fileKey));
+ }
+ Long projectId = component.projectId();
+ Long subProjectId = component.subProjectId();
+ // projectId and subProjectId can't be null here
+ if (projectId != null && subProjectId != null) {
+ List<PropertyDto> propertyDtos = propertiesDao.selectByQuery(PropertyQuery.builder()
+ .setKey("favourite")
+ .setComponentId(component.getId())
+ .setUserId(userSession.userId())
+ .build(),
+ session
+ );
+ boolean isFavourite = propertyDtos.size() == 1;
+
+ json.prop("key", component.key());
+ json.prop("path", component.path());
+ json.prop("name", component.name());
+ json.prop("q", component.qualifier());
+
+ Component subProject = componentById(subProjectId, session);
+ json.prop("subProjectName", subProject != null ? subProject.longName() : null);
+
+ Component project = componentById(projectId, session);
+ json.prop("projectName", project != null ? project.longName() : null);
+
+ json.prop("fav", isFavourite);
+ appendPeriods(json, projectId, session);
+ appendRulesAggregation(json, component.key(), session);
+ appendMeasures(json, fileKey, session);
+ }
+ } finally {
+ MyBatis.closeQuietly(session);
}
+
json.endObject();
json.close();
}
- private void appendMeasures(JsonWriter json, String fileKey) {
+ private void appendMeasures(JsonWriter json, String fileKey, DbSession session) {
json.name("measures").beginObject();
- json.prop("fNcloc", formattedMeasure(fileKey, CoreMetrics.NCLOC));
- json.prop("fCoverage", formattedMeasure(fileKey, CoreMetrics.COVERAGE));
- json.prop("fDuplicationDensity", formattedMeasure(fileKey, CoreMetrics.DUPLICATED_LINES_DENSITY));
- json.prop("fDebt", formattedMeasure(fileKey, CoreMetrics.TECHNICAL_DEBT));
- json.prop("fIssues", formattedMeasure(fileKey, CoreMetrics.VIOLATIONS));
- json.prop("fBlockerIssues", formattedMeasure(fileKey, CoreMetrics.BLOCKER_VIOLATIONS));
- json.prop("fCriticalIssues", formattedMeasure(fileKey, CoreMetrics.CRITICAL_VIOLATIONS));
- json.prop("fMajorIssues", formattedMeasure(fileKey, CoreMetrics.MAJOR_VIOLATIONS));
- json.prop("fMinorIssues", formattedMeasure(fileKey, CoreMetrics.MINOR_VIOLATIONS));
- json.prop("fInfoIssues", formattedMeasure(fileKey, CoreMetrics.INFO_VIOLATIONS));
+
+ List<MeasureDto> measures = measureDao.findByComponentKeyAndMetricKeys(fileKey,
+ newArrayList(CoreMetrics.NCLOC_KEY, CoreMetrics.COVERAGE_KEY, CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, CoreMetrics.TECHNICAL_DEBT_KEY, CoreMetrics.VIOLATIONS_KEY,
+ CoreMetrics.BLOCKER_VIOLATIONS_KEY, CoreMetrics.MAJOR_VIOLATIONS_KEY, CoreMetrics.MAJOR_VIOLATIONS_KEY, CoreMetrics.MINOR_VIOLATIONS_KEY, CoreMetrics.INFO_VIOLATIONS_KEY),
+ session
+ );
+
+ json.prop("fNcloc", formattedMeasure(CoreMetrics.NCLOC_KEY, measures));
+ json.prop("fCoverage", formattedMeasure(CoreMetrics.COVERAGE_KEY, measures));
+ json.prop("fDuplicationDensity", formattedMeasure(CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, measures));
+ json.prop("fDebt", formattedMeasure(CoreMetrics.TECHNICAL_DEBT_KEY, measures));
+ json.prop("fIssues", formattedMeasure(CoreMetrics.VIOLATIONS_KEY, measures));
+ json.prop("fBlockerIssues", formattedMeasure(CoreMetrics.BLOCKER_VIOLATIONS_KEY, measures));
+ json.prop("fCriticalIssues", formattedMeasure(CoreMetrics.CRITICAL_VIOLATIONS_KEY, measures));
+ json.prop("fMajorIssues", formattedMeasure(CoreMetrics.MAJOR_VIOLATIONS_KEY, measures));
+ json.prop("fMinorIssues", formattedMeasure(CoreMetrics.MINOR_VIOLATIONS_KEY, measures));
+ json.prop("fInfoIssues", formattedMeasure(CoreMetrics.INFO_VIOLATIONS_KEY, measures));
json.endObject();
}
- private void appendPeriods(JsonWriter json, Long projectId) {
+ private void appendPeriods(JsonWriter json, Long projectId, DbSession session) {
json.name("periods").beginArray();
- SnapshotDto snapshotDto = resourceDao.getLastSnapshotByResourceId(projectId);
+ SnapshotDto snapshotDto = resourceDao.getLastSnapshotByResourceId(projectId, session);
if (snapshotDto != null) {
for (int i = 1; i <= 5; i++) {
String mode = snapshotDto.getPeriodMode(i);
@@ -172,9 +197,9 @@ public class ComponentAppAction implements RequestHandler {
json.endArray();
}
- private void appendRulesAggregation(JsonWriter json, String componentKey) {
+ private void appendRulesAggregation(JsonWriter json, String componentKey, DbSession session) {
json.name("severities").beginArray();
- Multiset<String> severities = issueService.findSeveritiesByComponent(componentKey);
+ Multiset<String> severities = issueService.findSeveritiesByComponent(componentKey, session);
for (String severity : severities.elementSet()) {
json.beginArray()
.value(severity)
@@ -185,7 +210,7 @@ public class ComponentAppAction implements RequestHandler {
json.endArray();
json.name("rules").beginArray();
- RulesAggregation rulesAggregation = issueService.findRulesByComponent(componentKey);
+ RulesAggregation rulesAggregation = issueService.findRulesByComponent(componentKey, session);
for (RulesAggregation.Rule rule : rulesAggregation.rules()) {
json.beginArray()
.value(rule.ruleKey().toString())
@@ -197,18 +222,19 @@ public class ComponentAppAction implements RequestHandler {
}
@CheckForNull
- private Component componentById(@Nullable Long componentId) {
+ private Component componentById(@Nullable Long componentId, DbSession session) {
if (componentId != null) {
- return resourceDao.findById(componentId);
+ return resourceDao.findById(componentId, session);
}
return null;
}
@CheckForNull
- private String formattedMeasure(String fileKey, Metric metric) {
- MeasureDto measureDto = measureDao.findByComponentKeyAndMetricKey(fileKey, metric.getKey());
- if (measureDto != null) {
- Double value = measureDto.getValue();
+ private String formattedMeasure(final String metricKey, List<MeasureDto> measures) {
+ MeasureDto measure = measureByMetricKey(metricKey, measures);
+ if (measure != null) {
+ Metric metric = CoreMetrics.getMetric(measure.getKey().metricKey());
+ Double value = measure.getValue();
if (value != null) {
if (metric.getType().equals(Metric.ValueType.FLOAT)) {
return i18n.formatDouble(UserSession.get().locale(), value);
@@ -224,4 +250,14 @@ public class ComponentAppAction implements RequestHandler {
return null;
}
+ @CheckForNull
+ private static MeasureDto measureByMetricKey(final String metricKey, List<MeasureDto> measures) {
+ return Iterables.find(measures, new Predicate<MeasureDto>() {
+ @Override
+ public boolean apply(@Nullable MeasureDto input) {
+ return input != null && metricKey.equals(input.getKey().metricKey());
+ }
+ }, null);
+ }
+
}
diff --git a/sonar-server/src/main/java/org/sonar/server/db/BaseDao.java b/sonar-server/src/main/java/org/sonar/server/db/BaseDao.java
index 47e2df76129..d50ee8711be 100644
--- a/sonar-server/src/main/java/org/sonar/server/db/BaseDao.java
+++ b/sonar-server/src/main/java/org/sonar/server/db/BaseDao.java
@@ -22,8 +22,8 @@ package org.sonar.server.db;
import com.google.common.base.Preconditions;
import org.sonar.api.DaoComponent;
import org.sonar.api.utils.System2;
-import org.sonar.core.persistence.Dto;
import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.Dto;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.search.IndexDefinition;
import org.sonar.server.search.action.DtoIndexAction;
@@ -31,6 +31,8 @@ import org.sonar.server.search.action.EmbeddedIndexAction;
import org.sonar.server.search.action.IndexAction;
import org.sonar.server.search.action.KeyIndexAction;
+import javax.annotation.Nullable;
+
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
@@ -107,18 +109,26 @@ import java.util.List;
*/
public abstract class BaseDao<M, E extends Dto<K>, K extends Serializable> implements Dao<E, K>, DaoComponent {
- protected final IndexDefinition indexDefinition;
+ protected IndexDefinition indexDefinition;
private Class<M> mapperClass;
private System2 system2;
- protected BaseDao(IndexDefinition indexDefinition, Class<M> mapperClass, System2 system2) {
+ private boolean hasIndex() {
+ return indexDefinition != null;
+ }
+
+ protected BaseDao(@Nullable IndexDefinition indexDefinition, Class<M> mapperClass, System2 system2) {
this.mapperClass = mapperClass;
this.indexDefinition = indexDefinition;
this.system2 = system2;
}
+ protected BaseDao(Class<M> mapperClass, System2 system2) {
+ this(null, mapperClass, system2);
+ }
+
public String getIndexType() {
- return this.indexDefinition.getIndexType();
+ return indexDefinition != null ? this.indexDefinition.getIndexType() : null;
}
protected abstract E doGetByKey(K key, DbSession session);
@@ -149,7 +159,9 @@ public abstract class BaseDao<M, E extends Dto<K>, K extends Serializable> imple
public E update(E item, DbSession session) {
item.setUpdatedAt(new Date(system2.now()));
this.doUpdate(item, session);
- session.enqueue(new DtoIndexAction<E>(this.getIndexType(), IndexAction.Method.UPDATE, item));
+ if (hasIndex()) {
+ session.enqueue(new DtoIndexAction<E>(this.getIndexType(), IndexAction.Method.UPDATE, item));
+ }
return item;
}
@@ -168,7 +180,9 @@ public abstract class BaseDao<M, E extends Dto<K>, K extends Serializable> imple
item.setCreatedAt(new Date(system2.now()));
item.setUpdatedAt(item.getCreatedAt());
this.doInsert(item, session);
- session.enqueue(new DtoIndexAction<E>(this.getIndexType(), IndexAction.Method.INSERT, item));
+ if (hasIndex()) {
+ session.enqueue(new DtoIndexAction<E>(this.getIndexType(), IndexAction.Method.INSERT, item));
+ }
return item;
}
@@ -199,21 +213,29 @@ public abstract class BaseDao<M, E extends Dto<K>, K extends Serializable> imple
public void deleteByKey(K key, DbSession session) {
Preconditions.checkNotNull(key, "cannot delete Item with null key");
doDeleteByKey(key, session);
- session.enqueue(new KeyIndexAction<K>(this.getIndexType(), IndexAction.Method.DELETE, key));
+ if (hasIndex()) {
+ session.enqueue(new KeyIndexAction<K>(this.getIndexType(), IndexAction.Method.DELETE, key));
+ }
}
protected void enqueueUpdate(Object nestedItem, K key, DbSession session) {
- session.enqueue(new EmbeddedIndexAction<K>(
- this.getIndexType(), IndexAction.Method.UPDATE, nestedItem, key));
+ if (hasIndex()) {
+ session.enqueue(new EmbeddedIndexAction<K>(
+ this.getIndexType(), IndexAction.Method.UPDATE, nestedItem, key));
+ }
}
public void enqueueDelete(Object nestedItem, K key, DbSession session) {
- session.enqueue(new EmbeddedIndexAction<K>(
- this.getIndexType(), IndexAction.Method.DELETE, nestedItem, key));
+ if (hasIndex()) {
+ session.enqueue(new EmbeddedIndexAction<K>(
+ this.getIndexType(), IndexAction.Method.DELETE, nestedItem, key));
+ }
}
public void enqueueInsert(Object nestedItem, K key, DbSession session) {
- session.enqueue(new EmbeddedIndexAction<K>(
- this.getIndexType(), IndexAction.Method.INSERT, nestedItem, key));
+ if (hasIndex()) {
+ session.enqueue(new EmbeddedIndexAction<K>(
+ this.getIndexType(), IndexAction.Method.INSERT, nestedItem, key));
+ }
}
}
diff --git a/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java b/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
index 774bca951be..29f7dece639 100644
--- a/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
+++ b/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
@@ -45,6 +45,7 @@ import org.sonar.core.issue.db.IssueDao;
import org.sonar.core.issue.db.IssueStorage;
import org.sonar.core.issue.workflow.IssueWorkflow;
import org.sonar.core.issue.workflow.Transition;
+import org.sonar.core.persistence.DbSession;
import org.sonar.core.preview.PreviewCache;
import org.sonar.core.resource.ResourceDao;
import org.sonar.core.resource.ResourceDto;
@@ -280,18 +281,18 @@ public class IssueService implements ServerComponent {
}
// TODO result should be replaced by an aggregation object in IssueIndex
- public RulesAggregation findRulesByComponent(String componentKey) {
+ public RulesAggregation findRulesByComponent(String componentKey, DbSession session) {
RulesAggregation rulesAggregation = new RulesAggregation();
- for (RuleDto ruleDto : issueDao.findRulesByComponent(componentKey)) {
+ for (RuleDto ruleDto : issueDao.findRulesByComponent(componentKey, session)) {
rulesAggregation.add(ruleDto);
}
return rulesAggregation;
}
// TODO result should be replaced by an aggregation object in IssueIndex
- public Multiset<String> findSeveritiesByComponent(String componentKey) {
+ public Multiset<String> findSeveritiesByComponent(String componentKey, DbSession session) {
Multiset<String> aggregation = HashMultiset.create();
- for (String severity : issueDao.findSeveritiesByComponent(componentKey)) {
+ for (String severity : issueDao.findSeveritiesByComponent(componentKey, session)) {
aggregation.add(severity);
}
return aggregation;
diff --git a/sonar-server/src/main/java/org/sonar/server/measure/persistence/MeasureDao.java b/sonar-server/src/main/java/org/sonar/server/measure/persistence/MeasureDao.java
new file mode 100644
index 00000000000..9303d974145
--- /dev/null
+++ b/sonar-server/src/main/java/org/sonar/server/measure/persistence/MeasureDao.java
@@ -0,0 +1,86 @@
+/*
+ * 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.measure.persistence;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+import org.sonar.api.DaoComponent;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.utils.System2;
+import org.sonar.core.measure.db.MeasureDto;
+import org.sonar.core.measure.db.MeasureKey;
+import org.sonar.core.measure.db.MeasureMapper;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.server.db.BaseDao;
+
+import java.util.Collections;
+import java.util.List;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+public class MeasureDao extends BaseDao<MeasureMapper, MeasureDto, MeasureKey> implements ServerComponent, DaoComponent {
+
+ public MeasureDao() {
+ this(System2.INSTANCE);
+ }
+
+ @VisibleForTesting
+ public MeasureDao(System2 system) {
+ super(MeasureMapper.class, system);
+ }
+
+ @Override
+ protected MeasureDto doGetByKey(MeasureKey key, DbSession session) {
+ return session.getMapper(MeasureMapper.class).selectByKey(key);
+ }
+
+ public List<MeasureDto> findByComponentKeyAndMetricKeys(String componentKey, List<String> metricKeys, DbSession session){
+ if (metricKeys.isEmpty()) {
+ return Collections.emptyList();
+ }
+ List<MeasureDto> dtos = newArrayList();
+ List<List<String>> partitions = Lists.partition(newArrayList(metricKeys), 1000);
+ for (List<String> partition : partitions) {
+ dtos.addAll(session.getMapper(MeasureMapper.class).selectByComponentAndMetrics(componentKey, partition));
+ }
+ return dtos;
+ }
+
+ @Override
+ protected MeasureDto doInsert(MeasureDto item, DbSession session) {
+ throw new IllegalStateException("Not implemented yet");
+ }
+
+ @Override
+ protected MeasureDto doUpdate(MeasureDto item, DbSession session) {
+ throw new IllegalStateException("Not implemented yet");
+ }
+
+ @Override
+ protected void doDeleteByKey(MeasureKey key, DbSession session) {
+ throw new IllegalStateException("Not implemented yet");
+ }
+
+ @Override
+ public Iterable<MeasureKey> keysOfRowsUpdatedAfter(long timestamp, DbSession session) {
+ throw new IllegalStateException("Not implemented yet");
+ }
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
index 6173d0bee2c..7521680a5c1 100644
--- a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
+++ b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
@@ -50,9 +50,6 @@ import org.sonar.core.issue.IssueUpdater;
import org.sonar.core.issue.workflow.FunctionExecutor;
import org.sonar.core.issue.workflow.IssueWorkflow;
import org.sonar.core.measure.db.MeasureFilterDao;
-import org.sonar.server.measure.MeasureFilterEngine;
-import org.sonar.server.measure.MeasureFilterExecutor;
-import org.sonar.server.measure.MeasureFilterFactory;
import org.sonar.core.metric.DefaultMetricFinder;
import org.sonar.core.notification.DefaultNotificationManager;
import org.sonar.core.permission.PermissionFacade;
@@ -102,6 +99,10 @@ import org.sonar.server.issue.filter.IssueFilterWriter;
import org.sonar.server.issue.filter.IssueFilterWs;
import org.sonar.server.issue.ws.IssueShowAction;
import org.sonar.server.issue.ws.IssuesWs;
+import org.sonar.server.measure.MeasureFilterEngine;
+import org.sonar.server.measure.MeasureFilterExecutor;
+import org.sonar.server.measure.MeasureFilterFactory;
+import org.sonar.server.measure.persistence.MeasureDao;
import org.sonar.server.measure.ws.TimeMachineWs;
import org.sonar.server.notifications.NotificationCenter;
import org.sonar.server.notifications.NotificationService;
@@ -129,11 +130,7 @@ import org.sonar.server.rule2.RuleService;
import org.sonar.server.rule2.index.RuleIndex;
import org.sonar.server.rule2.index.RuleNormalizer;
import org.sonar.server.rule2.persistence.RuleDao;
-import org.sonar.server.rule2.ws.RulesWebService;
-import org.sonar.server.rule2.ws.SearchAction;
-import org.sonar.server.rule2.ws.SetNoteAction;
-import org.sonar.server.rule2.ws.SetTagsAction;
-import org.sonar.server.rule2.ws.TagsAction;
+import org.sonar.server.rule2.ws.*;
import org.sonar.server.source.CodeColorizers;
import org.sonar.server.source.DeprecatedSourceDecorator;
import org.sonar.server.source.HtmlSourceDecorator;
@@ -201,6 +198,7 @@ class ServerComponents {
System2.INSTANCE,
RuleDao.class,
ActiveRuleDao.class,
+ MeasureDao.class,
DbClient.class,
MeasureFilterDao.class
));
diff --git a/sonar-server/src/main/java/org/sonar/server/source/SourceService.java b/sonar-server/src/main/java/org/sonar/server/source/SourceService.java
index cbab7733a55..1ca84b94785 100644
--- a/sonar-server/src/main/java/org/sonar/server/source/SourceService.java
+++ b/sonar-server/src/main/java/org/sonar/server/source/SourceService.java
@@ -23,8 +23,11 @@ package org.sonar.server.source;
import org.sonar.api.ServerComponent;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.web.UserRole;
-import org.sonar.core.measure.db.MeasureDao;
import org.sonar.core.measure.db.MeasureDto;
+import org.sonar.core.measure.db.MeasureKey;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.server.measure.persistence.MeasureDao;
import org.sonar.server.user.UserSession;
import javax.annotation.CheckForNull;
@@ -34,6 +37,8 @@ import java.util.List;
public class SourceService implements ServerComponent {
+ private final MyBatis myBatis;
+
private final HtmlSourceDecorator sourceDecorator;
/**
@@ -43,7 +48,8 @@ public class SourceService implements ServerComponent {
private final MeasureDao measureDao;
- public SourceService(HtmlSourceDecorator sourceDecorator, DeprecatedSourceDecorator deprecatedSourceDecorator, MeasureDao measureDao) {
+ public SourceService(MyBatis myBatis, HtmlSourceDecorator sourceDecorator, DeprecatedSourceDecorator deprecatedSourceDecorator, MeasureDao measureDao) {
+ this.myBatis = myBatis;
this.sourceDecorator = sourceDecorator;
this.deprecatedSourceDecorator = deprecatedSourceDecorator;
this.measureDao = measureDao;
@@ -85,10 +91,15 @@ public class SourceService implements ServerComponent {
@CheckForNull
private String findDataFromComponent(String fileKey, String metricKey) {
- MeasureDto data = measureDao.findByComponentKeyAndMetricKey(fileKey, metricKey);
- if (data != null) {
- return data.getData();
+ DbSession session = myBatis.openSession(false);
+ try {
+ MeasureDto data = measureDao.getByKey(MeasureKey.of(fileKey, metricKey), session);
+ if (data != null) {
+ return data.getData();
+ }
+ return null;
+ } finally {
+ MyBatis.closeQuietly(session);
}
- return null;
}
}
diff --git a/sonar-server/src/main/java/org/sonar/server/test/CoverageService.java b/sonar-server/src/main/java/org/sonar/server/test/CoverageService.java
index 28ac0299002..5b5062fcd6b 100644
--- a/sonar-server/src/main/java/org/sonar/server/test/CoverageService.java
+++ b/sonar-server/src/main/java/org/sonar/server/test/CoverageService.java
@@ -28,8 +28,11 @@ import org.sonar.api.test.Testable;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.SnapshotPerspectives;
-import org.sonar.core.measure.db.MeasureDao;
import org.sonar.core.measure.db.MeasureDto;
+import org.sonar.core.measure.db.MeasureKey;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.server.measure.persistence.MeasureDao;
import org.sonar.server.user.UserSession;
import javax.annotation.CheckForNull;
@@ -42,10 +45,12 @@ public class CoverageService implements ServerComponent {
UT, IT, OVERALL
}
+ private final MyBatis myBatis;
private final MeasureDao measureDao;
private final SnapshotPerspectives snapshotPerspectives;
- public CoverageService(MeasureDao measureDao, SnapshotPerspectives snapshotPerspectives) {
+ public CoverageService(MyBatis myBatis, MeasureDao measureDao, SnapshotPerspectives snapshotPerspectives) {
+ this.myBatis = myBatis;
this.measureDao = measureDao;
this.snapshotPerspectives = snapshotPerspectives;
}
@@ -102,10 +107,15 @@ public class CoverageService implements ServerComponent {
@CheckForNull
private Map<Integer, Integer> findDataFromComponent(String fileKey, String metricKey) {
- MeasureDto data = measureDao.findByComponentKeyAndMetricKey(fileKey, metricKey);
- if (data != null) {
- return KeyValueFormat.parseIntInt(data.getData());
+ DbSession session = myBatis.openSession(false);
+ try {
+ MeasureDto data = measureDao.getByKey(MeasureKey.of(fileKey, metricKey), session);
+ if (data != null) {
+ return KeyValueFormat.parseIntInt(data.getData());
+ }
+ return Maps.newHashMap();
+ } finally {
+ MyBatis.closeQuietly(session);
}
- return Maps.newHashMap();
}
}
diff --git a/sonar-server/src/main/java/org/sonar/server/user/UserSession.java b/sonar-server/src/main/java/org/sonar/server/user/UserSession.java
index cf3ffe6b7b4..ec3a179f57f 100644
--- a/sonar-server/src/main/java/org/sonar/server/user/UserSession.java
+++ b/sonar-server/src/main/java/org/sonar/server/user/UserSession.java
@@ -36,12 +36,10 @@ import org.sonar.server.platform.Platform;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Locale;
+import java.util.*;
import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Maps.newHashMap;
/**
* Part of the current HTTP session
@@ -61,7 +59,7 @@ public class UserSession {
List<String> globalPermissions = null;
HashMultimap<String, String> projectKeyByPermission = HashMultimap.create();
- HashMultimap<String, String> componentKeyByPermission = HashMultimap.create();
+ Map<String, String> projectKeyByComponentKey = newHashMap();
List<String> projectPermissions = newArrayList();
UserSession() {
@@ -163,11 +161,17 @@ public class UserSession {
* Ensures that user implies the specified project permission on a component. If not a {@link org.sonar.server.exceptions.ForbiddenException} is thrown.
*/
public UserSession checkComponentPermission(String projectPermission, String componentKey) {
- ResourceDto project = resourceDao().getRootProjectByComponentKey(componentKey);
- if (project == null) {
- throw new NotFoundException(String.format("Component '%s' does not exist", componentKey));
+ String projectKey = projectKeyByComponentKey.get(componentKey);
+ if (projectKey == null) {
+ ResourceDto project = resourceDao().getRootProjectByComponentKey(componentKey);
+ if (project == null) {
+ throw new NotFoundException(String.format("Component '%s' does not exist", componentKey));
+ }
+ projectKey = project.getKey();
}
- return checkProjectPermission(projectPermission, project.getKey());
+ UserSession userSession = checkProjectPermission(projectPermission, projectKey);
+ projectKeyByComponentKey.put(componentKey, projectKey);
+ return userSession;
}
/**
diff --git a/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java b/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java
index 24d5adc52f9..ae95130a2d3 100644
--- a/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java
@@ -34,8 +34,9 @@ import org.sonar.api.utils.Duration;
import org.sonar.api.utils.Durations;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.ComponentDto;
-import org.sonar.core.measure.db.MeasureDao;
import org.sonar.core.measure.db.MeasureDto;
+import org.sonar.core.measure.db.MeasureKey;
+import org.sonar.core.persistence.DbSession;
import org.sonar.core.properties.PropertiesDao;
import org.sonar.core.properties.PropertyDto;
import org.sonar.core.properties.PropertyQuery;
@@ -43,12 +44,15 @@ import org.sonar.core.resource.ResourceDao;
import org.sonar.core.resource.SnapshotDto;
import org.sonar.core.rule.RuleDto;
import org.sonar.core.timemachine.Periods;
+import org.sonar.server.db.DbClient;
import org.sonar.server.issue.IssueService;
import org.sonar.server.issue.RulesAggregation;
+import org.sonar.server.measure.persistence.MeasureDao;
import org.sonar.server.user.MockUserSession;
import org.sonar.server.ws.WsTester;
import java.util.Date;
+import java.util.List;
import java.util.Locale;
import static com.google.common.collect.Lists.newArrayList;
@@ -63,15 +67,18 @@ public class ComponentAppActionTest {
static final String COMPONENT_KEY = "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java";
@Mock
- ResourceDao resourceDao;
+ DbSession session;
@Mock
- MeasureDao measureDao;
+ ResourceDao resourceDao;
@Mock
PropertiesDao propertiesDao;
@Mock
+ MeasureDao measureDao;
+
+ @Mock
IssueService issueService;
@Mock
@@ -83,26 +90,35 @@ public class ComponentAppActionTest {
@Mock
I18n i18n;
+ List<MeasureDto> measures = newArrayList();
+
WsTester tester;
@Before
public void setUp() throws Exception {
- when(issueService.findSeveritiesByComponent(COMPONENT_KEY)).thenReturn(mock(Multiset.class));
- when(issueService.findRulesByComponent(COMPONENT_KEY)).thenReturn(mock(RulesAggregation.class));
+ DbClient dbClient = mock(DbClient.class);
+ when(dbClient.openSession(false)).thenReturn(session);
+ when(dbClient.getDao(ResourceDao.class)).thenReturn(resourceDao);
+ when(dbClient.getDao(PropertiesDao.class)).thenReturn(propertiesDao);
+ when(dbClient.getDao(MeasureDao.class)).thenReturn(measureDao);
- tester = new WsTester(new ComponentsWs(new ComponentAppAction(resourceDao, measureDao, propertiesDao, issueService, periods, durations, i18n)));
+ when(issueService.findSeveritiesByComponent(COMPONENT_KEY, session)).thenReturn(mock(Multiset.class));
+ when(issueService.findRulesByComponent(COMPONENT_KEY, session)).thenReturn(mock(RulesAggregation.class));
+ when(measureDao.findByComponentKeyAndMetricKeys(eq(COMPONENT_KEY), anyListOf(String.class), eq(session))).thenReturn(measures);
+
+ tester = new WsTester(new ComponentsWs(new ComponentAppAction(dbClient, issueService, periods, durations, i18n)));
}
@Test
public void app() throws Exception {
- MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, PROJECT_KEY).addComponent(COMPONENT_KEY, PROJECT_KEY);
+ MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, PROJECT_KEY, COMPONENT_KEY);
ComponentDto file = new ComponentDto().setId(10L).setQualifier("FIL").setKey(COMPONENT_KEY).setName("Plugin.java")
.setPath("src/main/java/org/sonar/api/Plugin.java").setSubProjectId(5L).setProjectId(1L);
- when(resourceDao.selectComponentByKey(COMPONENT_KEY)).thenReturn(file);
- when(resourceDao.findById(5L)).thenReturn(new ComponentDto().setId(5L).setLongName("SonarQube :: Plugin API"));
- when(resourceDao.findById(1L)).thenReturn(new ComponentDto().setId(1L).setLongName("SonarQube"));
- when(propertiesDao.selectByQuery(any(PropertyQuery.class))).thenReturn(newArrayList(new PropertyDto()));
+ when(resourceDao.selectComponentByKey(COMPONENT_KEY, session)).thenReturn(file);
+ when(resourceDao.findById(5L, session)).thenReturn(new ComponentDto().setId(5L).setLongName("SonarQube :: Plugin API"));
+ when(resourceDao.findById(1L, session)).thenReturn(new ComponentDto().setId(1L).setLongName("SonarQube"));
+ when(propertiesDao.selectByQuery(any(PropertyQuery.class), eq(session))).thenReturn(newArrayList(new PropertyDto()));
WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("key", COMPONENT_KEY);
request.execute().assertJson(getClass(), "app.json");
@@ -110,7 +126,7 @@ public class ComponentAppActionTest {
@Test
public void app_with_measures() throws Exception {
- MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, PROJECT_KEY).addComponent(COMPONENT_KEY, PROJECT_KEY);
+ MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, PROJECT_KEY, COMPONENT_KEY);
addProjectSample();
@@ -124,7 +140,7 @@ public class ComponentAppActionTest {
addMeasure(CoreMetrics.MINOR_VIOLATIONS_KEY, 4);
addMeasure(CoreMetrics.INFO_VIOLATIONS_KEY, 2);
- when(measureDao.findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.TECHNICAL_DEBT_KEY)).thenReturn(new MeasureDto().setValue(182.0));
+ measures.add(MeasureDto.createFor(MeasureKey.of(COMPONENT_KEY, CoreMetrics.TECHNICAL_DEBT_KEY)).setValue(182.0));
when(durations.format(any(Locale.class), any(Duration.class), eq(Durations.DurationFormat.SHORT))).thenReturn("3h 2min");
WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("key", COMPONENT_KEY);
@@ -133,11 +149,11 @@ public class ComponentAppActionTest {
@Test
public void app_with_periods() throws Exception {
- MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, PROJECT_KEY).addComponent(COMPONENT_KEY, PROJECT_KEY);
+ MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, PROJECT_KEY, COMPONENT_KEY);
addProjectSample();
- when(resourceDao.getLastSnapshotByResourceId(eq(1L))).thenReturn(
+ when(resourceDao.getLastSnapshotByResourceId(eq(1L), eq(session))).thenReturn(
new SnapshotDto().setPeriod1Mode("previous_analysis").setPeriod1Date(DateUtils.parseDate("2014-05-08"))
);
when(periods.label(anyString(), anyString(), any(Date.class))).thenReturn("since previous analysis (May 08 2014)");
@@ -148,13 +164,13 @@ public class ComponentAppActionTest {
@Test
public void app_with_severities() throws Exception {
- MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, PROJECT_KEY).addComponent(COMPONENT_KEY, PROJECT_KEY);
+ MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, PROJECT_KEY, COMPONENT_KEY);
addProjectSample();
Multiset<String> severities = HashMultiset.create();
severities.add("MAJOR", 5);
- when(issueService.findSeveritiesByComponent(COMPONENT_KEY)).thenReturn(severities);
+ when(issueService.findSeveritiesByComponent(COMPONENT_KEY, session)).thenReturn(severities);
when(i18n.message(any(Locale.class), eq("severity.MAJOR"), isNull(String.class))).thenReturn("Major");
WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("key", COMPONENT_KEY);
@@ -163,10 +179,10 @@ public class ComponentAppActionTest {
@Test
public void app_with_rules() throws Exception {
- MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, PROJECT_KEY).addComponent(COMPONENT_KEY, PROJECT_KEY);
+ MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, PROJECT_KEY, COMPONENT_KEY);
addProjectSample();
- when(issueService.findRulesByComponent(COMPONENT_KEY)).thenReturn(
+ when(issueService.findRulesByComponent(COMPONENT_KEY, session)).thenReturn(
new RulesAggregation().add(new RuleDto().setRuleKey("AvoidCycle").setRepositoryKey("squid").setName("Avoid Cycle"))
);
@@ -177,19 +193,18 @@ public class ComponentAppActionTest {
private void addProjectSample() {
ComponentDto file = new ComponentDto().setId(10L).setQualifier("FIL").setKey(COMPONENT_KEY).setName("Plugin.java")
.setPath("src/main/java/org/sonar/api/Plugin.java").setSubProjectId(5L).setProjectId(1L);
- when(resourceDao.selectComponentByKey(COMPONENT_KEY)).thenReturn(file);
- when(resourceDao.findById(5L)).thenReturn(new ComponentDto().setId(5L).setLongName("SonarQube :: Plugin API"));
- when(resourceDao.findById(1L)).thenReturn(new ComponentDto().setId(1L).setLongName("SonarQube"));
-
+ when(resourceDao.selectComponentByKey(COMPONENT_KEY, session)).thenReturn(file);
+ when(resourceDao.findById(5L, session)).thenReturn(new ComponentDto().setId(5L).setLongName("SonarQube :: Plugin API"));
+ when(resourceDao.findById(1L, session)).thenReturn(new ComponentDto().setId(1L).setLongName("SonarQube"));
}
private void addMeasure(String metricKey, Integer value) {
- when(measureDao.findByComponentKeyAndMetricKey(COMPONENT_KEY, metricKey)).thenReturn(new MeasureDto().setValue(value.doubleValue()));
+ measures.add(MeasureDto.createFor(MeasureKey.of(COMPONENT_KEY, metricKey)).setValue(value.doubleValue()));
when(i18n.formatInteger(any(Locale.class), eq(value.intValue()))).thenReturn(Integer.toString(value));
}
private void addMeasure(String metricKey, Double value) {
- when(measureDao.findByComponentKeyAndMetricKey(COMPONENT_KEY, metricKey)).thenReturn(new MeasureDto().setValue(value));
+ measures.add(MeasureDto.createFor(MeasureKey.of(COMPONENT_KEY, metricKey)).setValue(value));
when(i18n.formatDouble(any(Locale.class), eq(value))).thenReturn(Double.toString(value));
}
diff --git a/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java b/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java
index 76f461113f4..c6358a587b1 100644
--- a/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java
@@ -26,10 +26,8 @@ import org.sonar.api.i18n.I18n;
import org.sonar.api.server.ws.RailsHandler;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.Durations;
-import org.sonar.core.measure.db.MeasureDao;
-import org.sonar.core.properties.PropertiesDao;
-import org.sonar.core.resource.ResourceDao;
import org.sonar.core.timemachine.Periods;
+import org.sonar.server.db.DbClient;
import org.sonar.server.issue.IssueService;
import org.sonar.server.ws.WsTester;
@@ -42,8 +40,7 @@ public class ComponentsWsTest {
@Before
public void setUp() throws Exception {
- WsTester tester = new WsTester(new ComponentsWs(new ComponentAppAction(mock(ResourceDao.class), mock(MeasureDao.class), mock(PropertiesDao.class),
- mock(IssueService.class), mock(Periods.class), mock(Durations.class), mock(I18n.class))));
+ WsTester tester = new WsTester(new ComponentsWs(new ComponentAppAction(mock(DbClient.class), mock(IssueService.class), mock(Periods.class), mock(Durations.class), mock(I18n.class))));
controller = tester.controller("api/components");
}
diff --git a/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceTest.java b/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceTest.java
index 745bc149649..27aebc4452c 100644
--- a/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceTest.java
@@ -20,6 +20,7 @@
package org.sonar.server.issue;
+import com.google.common.collect.Multiset;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -45,10 +46,12 @@ import org.sonar.core.issue.db.IssueDao;
import org.sonar.core.issue.db.IssueStorage;
import org.sonar.core.issue.workflow.IssueWorkflow;
import org.sonar.core.issue.workflow.Transition;
+import org.sonar.core.persistence.DbSession;
import org.sonar.core.preview.PreviewCache;
import org.sonar.core.resource.ResourceDao;
import org.sonar.core.resource.ResourceDto;
import org.sonar.core.resource.ResourceQuery;
+import org.sonar.core.rule.RuleDto;
import org.sonar.core.user.AuthorizationDao;
import org.sonar.core.user.DefaultUser;
import org.sonar.server.issue.actionplan.ActionPlanService;
@@ -499,4 +502,30 @@ public class IssueServiceTest {
verifyZeroInteractions(issueStorage);
}
+ @Test
+ public void find_rules_by_component() throws Exception {
+ DbSession session = mock(DbSession.class);
+ String componentKey = "org.sonar.Sample";
+
+ when(issueDao.findRulesByComponent(componentKey, session)).thenReturn(newArrayList(
+ RuleDto.createFor(RuleKey.of("repo", "rule")).setName("Rule name"),
+ RuleDto.createFor(RuleKey.of("repo", "rule")).setName("Rule name")
+ ));
+
+ RulesAggregation result = issueService.findRulesByComponent(componentKey, session);
+ assertThat(result.rules()).hasSize(1);
+ }
+
+ @Test
+ public void find_rules_by_severity() throws Exception {
+ DbSession session = mock(DbSession.class);
+ String componentKey = "org.sonar.Sample";
+
+ when(issueDao.findSeveritiesByComponent(componentKey, session)).thenReturn(newArrayList("MAJOR", "MAJOR", "INFO"));
+
+ Multiset<String> result = issueService.findSeveritiesByComponent(componentKey, session);
+ assertThat(result.count("MAJOR")).isEqualTo(2);
+ assertThat(result.count("INFO")).isEqualTo(1);
+ assertThat(result.count("UNKNOWN")).isEqualTo(0);
+ }
}
diff --git a/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java b/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java
new file mode 100644
index 00000000000..27755289041
--- /dev/null
+++ b/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.measure.persistence;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.core.measure.db.MeasureDto;
+import org.sonar.core.measure.db.MeasureKey;
+import org.sonar.core.persistence.AbstractDaoTestCase;
+import org.sonar.core.persistence.DbSession;
+
+import java.util.List;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.fest.assertions.Assertions.assertThat;
+
+public class MeasureDaoTest extends AbstractDaoTestCase {
+
+ DbSession session;
+
+ MeasureDao dao;
+
+ @Before
+ public void createDao() {
+ session = getMyBatis().openSession(false);
+ dao = new MeasureDao();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ session.close();
+ }
+
+ @Test
+ public void get_value_by_key() throws Exception {
+ setupData("shared");
+
+ MeasureDto result = dao.getByKey(MeasureKey.of("org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc"), session);
+ assertThat(result.getId()).isEqualTo(22);
+ assertThat(result.getValue()).isEqualTo(10d);
+ }
+
+ @Test
+ public void get_data_by_key() throws Exception {
+ setupData("shared");
+
+ MeasureDto result = dao.getByKey(MeasureKey.of("org.struts:struts-core:src/org/struts/RequestContext.java", "authors_by_line"), session);
+ assertThat(result.getId()).isEqualTo(20);
+ assertThat(result.getData()).isEqualTo("0123456789012345678901234567890123456789");
+ }
+
+ @Test
+ public void get_text_value_by_key() throws Exception {
+ setupData("shared");
+
+ MeasureDto result = dao.getByKey(MeasureKey.of("org.struts:struts-core:src/org/struts/RequestContext.java", "coverage_line_hits_data"), session);
+ assertThat(result.getId()).isEqualTo(21);
+ assertThat(result.getData()).isEqualTo("36=1;37=1;38=1;39=1;43=1;48=1;53=1");
+ }
+
+ @Test
+ public void find_by_component_key_and_metrics() throws Exception {
+ setupData("shared");
+
+ List<MeasureDto> results = dao.findByComponentKeyAndMetricKeys("org.struts:struts-core:src/org/struts/RequestContext.java",
+ newArrayList("ncloc", "authors_by_line"), session);
+ assertThat(results).hasSize(2);
+
+ results = dao.findByComponentKeyAndMetricKeys("org.struts:struts-core:src/org/struts/RequestContext.java", newArrayList("ncloc"), session);
+ assertThat(results).hasSize(1);
+
+ MeasureDto result = results.get(0);
+ assertThat(result.getId()).isEqualTo(22);
+ assertThat(result.getValue()).isEqualTo(10d);
+ assertThat(result.getKey()).isNotNull();
+ }
+}
diff --git a/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesMediumTest.java b/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesMediumTest.java
index 9cb5eed7689..3290a6154eb 100644
--- a/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesMediumTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesMediumTest.java
@@ -82,8 +82,7 @@ public class RegisterQualityProfilesMediumTest {
// 2. Check Default Profile
PropertiesDao propertiesDao = serverTester.get(PropertiesDao.class);
- List<PropertyDto> xooDefault = propertiesDao.selectByQuery(PropertyQuery.builder()
- .setKey("sonar.profile.xoo").build());
+ List<PropertyDto> xooDefault = propertiesDao.selectByQuery(PropertyQuery.builder().setKey("sonar.profile.xoo").build(), session);
assertThat(xooDefault).hasSize(1);
assertThat(xooDefault.get(0).getValue()).isEqualTo("Basic");
diff --git a/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java b/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java
index 91eca92a641..591631d5b52 100644
--- a/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java
@@ -27,8 +27,11 @@ import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.web.UserRole;
-import org.sonar.core.measure.db.MeasureDao;
+import org.sonar.core.measure.db.MeasureKey;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.measure.persistence.MeasureDao;
import org.sonar.server.user.MockUserSession;
import java.util.Collections;
@@ -41,6 +44,9 @@ import static org.mockito.Mockito.*;
public class SourceServiceTest {
@Mock
+ DbSession session;
+
+ @Mock
HtmlSourceDecorator sourceDecorator;
@Mock
@@ -53,14 +59,16 @@ public class SourceServiceTest {
@Before
public void setUp() throws Exception {
- service = new SourceService(sourceDecorator, deprecatedSourceDecorator, measureDao);
+ MyBatis myBatis = mock(MyBatis.class);
+ when(myBatis.openSession(false)).thenReturn(session);
+ service = new SourceService(myBatis, sourceDecorator, deprecatedSourceDecorator, measureDao);
}
@Test
public void get_lines() throws Exception {
String projectKey = "org.sonar.sample";
String componentKey = "org.sonar.sample:Sample";
- MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, projectKey).addComponent(componentKey, projectKey);
+ MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, projectKey, componentKey);
service.getLinesAsHtml(componentKey);
@@ -87,7 +95,7 @@ public class SourceServiceTest {
public void get_block_of_lines() throws Exception {
String projectKey = "org.sonar.sample";
String componentKey = "org.sonar.sample:Sample";
- MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, projectKey).addComponent(componentKey, projectKey);;
+ MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, projectKey, componentKey);
service.getLinesAsHtml(componentKey, 1, 2);
@@ -98,7 +106,7 @@ public class SourceServiceTest {
public void get_lines_from_deprecated_source_decorator_when_no_data_from_new_decorator() throws Exception {
String projectKey = "org.sonar.sample";
String componentKey = "org.sonar.sample:Sample";
- MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, projectKey).addComponent(componentKey, projectKey);;
+ MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, projectKey, componentKey);
when(sourceDecorator.getDecoratedSourceAsHtml(eq(componentKey), anyInt(), anyInt())).thenReturn(Collections.<String>emptyList());
service.getLinesAsHtml(componentKey, 1, 2);
@@ -110,13 +118,13 @@ public class SourceServiceTest {
public void get_scm_author_data() throws Exception {
String componentKey = "org.sonar.sample:Sample";
service.getScmAuthorData(componentKey);
- verify(measureDao).findByComponentKeyAndMetricKey(componentKey, CoreMetrics.SCM_AUTHORS_BY_LINE_KEY);
+ verify(measureDao).getByKey(MeasureKey.of(componentKey, CoreMetrics.SCM_AUTHORS_BY_LINE_KEY), session);
}
@Test
public void not_get_scm_author_data_if_no_data() throws Exception {
String componentKey = "org.sonar.sample:Sample";
- when(measureDao.findByComponentKeyAndMetricKey(eq(componentKey), anyString())).thenReturn(null);
+ when(measureDao.getByKey(any(MeasureKey.class), eq(session))).thenReturn(null);
assertThat(service.getScmAuthorData(componentKey)).isNull();
}
@@ -124,13 +132,13 @@ public class SourceServiceTest {
public void get_scm_date_data() throws Exception {
String componentKey = "org.sonar.sample:Sample";
service.getScmDateData(componentKey);
- verify(measureDao).findByComponentKeyAndMetricKey(componentKey, CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE_KEY);
+ verify(measureDao).getByKey(MeasureKey.of(componentKey, CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE_KEY), session);
}
@Test
public void not_get_scm_date_data_if_no_data() throws Exception {
String componentKey = "org.sonar.sample:Sample";
- when(measureDao.findByComponentKeyAndMetricKey(eq(componentKey), anyString())).thenReturn(null);
+ when(measureDao.getByKey(any(MeasureKey.class), eq(session))).thenReturn(null);
assertThat(service.getScmDateData(componentKey)).isNull();
}
}
diff --git a/sonar-server/src/test/java/org/sonar/server/test/CoverageServiceTest.java b/sonar-server/src/test/java/org/sonar/server/test/CoverageServiceTest.java
index 4d033dd383b..2311e57c20a 100644
--- a/sonar-server/src/test/java/org/sonar/server/test/CoverageServiceTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/test/CoverageServiceTest.java
@@ -30,13 +30,15 @@ import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.test.MutableTestable;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.SnapshotPerspectives;
-import org.sonar.core.measure.db.MeasureDao;
+import org.sonar.core.measure.db.MeasureKey;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.server.measure.persistence.MeasureDao;
import org.sonar.server.user.MockUserSession;
import java.util.Collections;
import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;
@@ -47,6 +49,9 @@ public class CoverageServiceTest {
public ExpectedException thrown = ExpectedException.none();
@Mock
+ DbSession session;
+
+ @Mock
MeasureDao measureDao;
@Mock
@@ -58,14 +63,15 @@ public class CoverageServiceTest {
@Before
public void setUp() throws Exception {
- service = new CoverageService(measureDao, snapshotPerspectives);
+ MyBatis myBatis = mock(MyBatis.class);
+ when(myBatis.openSession(false)).thenReturn(session);
+ service = new CoverageService(myBatis, measureDao, snapshotPerspectives);
}
@Test
public void check_permission() throws Exception {
String projectKey = "org.sonar.sample";
- MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, projectKey);
- MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, projectKey).addComponent(COMPONENT_KEY, projectKey);
+ MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, projectKey, COMPONENT_KEY);
service.checkPermission(COMPONENT_KEY);
}
@@ -73,43 +79,43 @@ public class CoverageServiceTest {
@Test
public void get_hits_data() throws Exception {
service.getHits(COMPONENT_KEY, CoverageService.TYPE.UT);
- verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY);
+ verify(measureDao).getByKey(MeasureKey.of(COMPONENT_KEY, CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY), session);
service.getHits(COMPONENT_KEY, CoverageService.TYPE.IT);
- verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY);
+ verify(measureDao).getByKey(MeasureKey.of(COMPONENT_KEY, CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY), session);
service.getHits(COMPONENT_KEY, CoverageService.TYPE.OVERALL);
- verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA_KEY);
+ verify(measureDao).getByKey(MeasureKey.of(COMPONENT_KEY, CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA_KEY), session);
}
@Test
public void not_get_hits_data_if_no_data() throws Exception {
- when(measureDao.findByComponentKeyAndMetricKey(eq(COMPONENT_KEY), anyString())).thenReturn(null);
+ when(measureDao.getByKey(any(MeasureKey.class), eq(session))).thenReturn(null);
assertThat(service.getHits(COMPONENT_KEY, CoverageService.TYPE.UT)).isEqualTo(Collections.emptyMap());
}
@Test
public void get_conditions_data() throws Exception {
service.getConditions(COMPONENT_KEY, CoverageService.TYPE.UT);
- verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.CONDITIONS_BY_LINE_KEY);
+ verify(measureDao).getByKey(MeasureKey.of(COMPONENT_KEY, CoreMetrics.CONDITIONS_BY_LINE_KEY), session);
service.getConditions(COMPONENT_KEY, CoverageService.TYPE.IT);
- verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.IT_CONDITIONS_BY_LINE_KEY);
+ verify(measureDao).getByKey(MeasureKey.of(COMPONENT_KEY, CoreMetrics.IT_CONDITIONS_BY_LINE_KEY), session);
service.getConditions(COMPONENT_KEY, CoverageService.TYPE.OVERALL);
- verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.OVERALL_CONDITIONS_BY_LINE_KEY);
+ verify(measureDao).getByKey(MeasureKey.of(COMPONENT_KEY, CoreMetrics.OVERALL_CONDITIONS_BY_LINE_KEY), session);
}
@Test
public void get_covered_conditions_data() throws Exception {
service.getCoveredConditions(COMPONENT_KEY, CoverageService.TYPE.UT);
- verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY);
+ verify(measureDao).getByKey(MeasureKey.of(COMPONENT_KEY, CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY), session);
service.getCoveredConditions(COMPONENT_KEY, CoverageService.TYPE.IT);
- verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE_KEY);
+ verify(measureDao).getByKey(MeasureKey.of(COMPONENT_KEY, CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE_KEY), session);
service.getCoveredConditions(COMPONENT_KEY, CoverageService.TYPE.OVERALL);
- verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE_KEY);
+ verify(measureDao).getByKey(MeasureKey.of(COMPONENT_KEY, CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE_KEY), session);
}
@Test
diff --git a/sonar-server/src/test/java/org/sonar/server/user/MockUserSession.java b/sonar-server/src/test/java/org/sonar/server/user/MockUserSession.java
index aa39fe5f4e5..8ca959dac2e 100644
--- a/sonar-server/src/test/java/org/sonar/server/user/MockUserSession.java
+++ b/sonar-server/src/test/java/org/sonar/server/user/MockUserSession.java
@@ -21,7 +21,6 @@ package org.sonar.server.user;
import com.google.common.collect.HashMultimap;
import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
import org.sonar.core.user.AuthorizationDao;
import javax.annotation.Nullable;
@@ -32,7 +31,6 @@ import java.util.Locale;
import static com.google.common.collect.Lists.newArrayList;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
public class MockUserSession extends UserSession {
@@ -88,8 +86,9 @@ public class MockUserSession extends UserSession {
return this;
}
- public MockUserSession addComponent(String componentKey, String projectKey) {
- when(resourceDao.getRootProjectByComponentKey(componentKey)).thenReturn(new ResourceDto().setKey(projectKey));
+ public MockUserSession addComponentPermission(String projectPermission, String projectKey, String componentKey) {
+ this.projectKeyByComponentKey.put(componentKey, projectKey);
+ addProjectPermissions(projectPermission, projectKey);
return this;
}
diff --git a/sonar-core/src/test/resources/org/sonar/core/measure/db/MeasureDaoTest/shared.xml b/sonar-server/src/test/resources/org/sonar/server/measure/persistence/MeasureDaoTest/shared.xml
index 70097c0470f..70097c0470f 100644
--- a/sonar-core/src/test/resources/org/sonar/core/measure/db/MeasureDaoTest/shared.xml
+++ b/sonar-server/src/test/resources/org/sonar/server/measure/persistence/MeasureDaoTest/shared.xml
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/package-info.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/package-info.java
new file mode 100644
index 00000000000..1a92c5c0269
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.wsclient.source.internal;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/source/package-info.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/package-info.java
new file mode 100644
index 00000000000..546965bbac9
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.wsclient.source;
+
+import javax.annotation.ParametersAreNonnullByDefault;