]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5305 Returned measures in /api/components/app
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 16 May 2014 10:01:26 +0000 (12:01 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 16 May 2014 10:01:26 +0000 (12:01 +0200)
26 files changed:
sonar-core/src/main/java/org/sonar/core/i18n/DefaultI18n.java
sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDao.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDataDao.java [deleted file]
sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDataDto.java [deleted file]
sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDataMapper.java [deleted file]
sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDto.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/measure/db/MeasureMapper.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java
sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
sonar-core/src/main/resources/org/sonar/core/measure/db/MeasureDataMapper.xml [deleted file]
sonar-core/src/main/resources/org/sonar/core/measure/db/MeasureMapper.xml [new file with mode: 0644]
sonar-core/src/test/java/org/sonar/core/i18n/DefaultI18nTest.java
sonar-core/src/test/java/org/sonar/core/measure/db/MeasureDaoTest.java [new file with mode: 0644]
sonar-core/src/test/java/org/sonar/core/measure/db/MeasureDataDaoTest.java [deleted file]
sonar-core/src/test/resources/org/sonar/core/measure/db/MeasureDaoTest/shared.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/measure/db/MeasureDataDaoTest/shared.xml [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/i18n/I18n.java
sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java
sonar-server/src/main/java/org/sonar/server/source/SourceService.java
sonar-server/src/main/java/org/sonar/server/test/CoverageService.java
sonar-server/src/main/resources/org/sonar/server/component/ws/components-app-example-show.json
sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java
sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java
sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java
sonar-server/src/test/java/org/sonar/server/test/CoverageServiceTest.java
sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app.json

index 4bf009a9a422e0f28afb82e23423d85a9e80f9da..0ce77a1baec77e0baf58599f85a9188cdbb1ed49 100644 (file)
@@ -39,7 +39,9 @@ import javax.annotation.Nullable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.text.DateFormat;
+import java.text.DecimalFormat;
 import java.text.MessageFormat;
+import java.text.NumberFormat;
 import java.util.*;
 
 public class DefaultI18n implements I18n, ServerExtension, BatchExtension, Startable {
@@ -94,7 +96,8 @@ public class DefaultI18n implements I18n, ServerExtension, BatchExtension, Start
     }
     LOG.debug(String.format("Loaded %d properties from l10n bundles", propertyToBundles.size()));
   }
-  private void addPlugin(String pluginKey){
+
+  private void addPlugin(String pluginKey) {
     try {
       String bundleKey = BUNDLE_PACKAGE + pluginKey;
       ResourceBundle bundle = ResourceBundle.getBundle(bundleKey, Locale.ENGLISH, this.classloader, control);
@@ -156,6 +159,17 @@ public class DefaultI18n implements I18n, ServerExtension, BatchExtension, Start
     return DateFormat.getDateInstance(DateFormat.DEFAULT, locale).format(date);
   }
 
+  public String formatDouble(Locale locale, Double value) {
+    NumberFormat format = DecimalFormat.getNumberInstance(locale);
+    format.setMinimumFractionDigits(1);
+    format.setMaximumFractionDigits(1);
+    return format.format(value);
+  }
+
+  public String formatInteger(Locale locale, Integer value) {
+    return NumberFormat.getNumberInstance(locale).format(value);
+  }
+
   /**
    * Only the given locale is searched. Contrary to java.util.ResourceBundle, no strategy for locating the bundle is implemented in
    * this method.
diff --git a/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDao.java b/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDao.java
new file mode 100644 (file)
index 0000000..c8a3e92
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.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);
+    }
+  }
+
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDataDao.java b/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDataDao.java
deleted file mode 100644 (file)
index 45aa4db..0000000
+++ /dev/null
@@ -1,45 +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.apache.ibatis.session.SqlSession;
-import org.sonar.api.ServerComponent;
-import org.sonar.core.persistence.MyBatis;
-
-public class MeasureDataDao implements ServerComponent {
-
-  private MyBatis mybatis;
-
-  public MeasureDataDao(MyBatis mybatis) {
-    this.mybatis = mybatis;
-  }
-
-  public MeasureDataDto findByComponentKeyAndMetricKey(String componentKey, String metricKey) {
-    SqlSession session = mybatis.openSession(false);
-    try {
-      MeasureDataMapper mapper = session.getMapper(MeasureDataMapper.class);
-      return mapper.findByComponentKeyAndMetricKey(componentKey, metricKey);
-    } finally {
-      MyBatis.closeQuietly(session);
-    }
-  }
-
-}
diff --git a/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDataDto.java b/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDataDto.java
deleted file mode 100644 (file)
index 0ddb30f..0000000
+++ /dev/null
@@ -1,67 +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 com.google.common.base.Charsets;
-
-import javax.annotation.CheckForNull;
-
-public class MeasureDataDto {
-
-  private Integer id;
-
-  private Integer snapshotId;
-
-  private String textValue;
-
-  private byte[] data;
-
-  public Integer getId() {
-    return id;
-  }
-
-  public MeasureDataDto setId(Integer id) {
-    this.id = id;
-    return this;
-  }
-
-  public Integer getSnapshotId() {
-    return snapshotId;
-  }
-
-  public MeasureDataDto setSnapshotId(Integer snapshotId) {
-    this.snapshotId = snapshotId;
-    return this;
-  }
-
-  public MeasureDataDto setData(byte[] data) {
-    this.data = data;
-    return this;
-  }
-
-  @CheckForNull
-  public String getData() {
-    if (data != null) {
-      return new String(data, Charsets.UTF_8);
-    }
-    return textValue;
-  }
-}
diff --git a/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDataMapper.java b/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDataMapper.java
deleted file mode 100644 (file)
index 51f28cb..0000000
+++ /dev/null
@@ -1,29 +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.apache.ibatis.annotations.Param;
-
-public interface MeasureDataMapper {
-
-  MeasureDataDto findByComponentKeyAndMetricKey(@Param("componentKey") String componentKey, @Param("metricKey") String metricKey);
-
-}
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
new file mode 100644 (file)
index 0000000..edbfe96
--- /dev/null
@@ -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.core.measure.db;
+
+import com.google.common.base.Charsets;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+public class MeasureDto {
+
+  private Integer id;
+
+  private Integer snapshotId;
+
+  private Double value;
+
+  private String textValue;
+
+  private byte[] data;
+
+  public Integer getId() {
+    return id;
+  }
+
+  public MeasureDto setId(Integer id) {
+    this.id = id;
+    return this;
+  }
+
+  public Integer getSnapshotId() {
+    return snapshotId;
+  }
+
+  public MeasureDto setSnapshotId(Integer snapshotId) {
+    this.snapshotId = snapshotId;
+    return this;
+  }
+
+  @CheckForNull
+  public Double getValue() {
+    return value;
+  }
+
+  public MeasureDto setValue(@Nullable Double value) {
+    this.value = value;
+    return this;
+  }
+
+  public MeasureDto setTextValue(String textValue) {
+    this.textValue = textValue;
+    return this;
+  }
+
+  @CheckForNull
+  public MeasureDto setData(@Nullable byte[] data) {
+    this.data = data;
+    return this;
+  }
+
+  @CheckForNull
+  public String getData() {
+    if (data != null) {
+      return new String(data, Charsets.UTF_8);
+    }
+    return textValue;
+  }
+}
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
new file mode 100644 (file)
index 0000000..fd27c9b
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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.apache.ibatis.annotations.Param;
+
+public interface MeasureMapper {
+
+  MeasureDto findByComponentKeyAndMetricKey(@Param("componentKey") String componentKey, @Param("metricKey") String metricKey);
+
+}
index 5c3e7b9ab73808141a853e5d6b55844b21a320d0..b45c9ac4bd0ab12aad038533c2d4c84b76f43df0 100644 (file)
@@ -25,7 +25,7 @@ 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.*;
-import org.sonar.core.measure.db.MeasureDataDao;
+import org.sonar.core.measure.db.MeasureDao;
 import org.sonar.core.measure.db.MeasureFilterDao;
 import org.sonar.core.notification.db.NotificationQueueDao;
 import org.sonar.core.permission.PermissionDao;
@@ -71,7 +71,7 @@ public final class DaoUtils {
       IssueFilterDao.class,
       IssueFilterFavouriteDao.class,
       LoadedTemplateDao.class,
-      MeasureDataDao.class,
+      MeasureDao.class,
       MeasureFilterDao.class,
       NotificationQueueDao.class,
       PermissionDao.class,
index 8998f8da543be827a4e8a61337397f0d9eed44a2..04328a8eb87f4235ed764ecc4c5ae45a3617e3a7 100644 (file)
@@ -24,30 +24,18 @@ import com.google.common.io.Closeables;
 import org.apache.ibatis.builder.xml.XMLMapperBuilder;
 import org.apache.ibatis.logging.LogFactory;
 import org.apache.ibatis.mapping.Environment;
-import org.apache.ibatis.session.Configuration;
-import org.apache.ibatis.session.ExecutorType;
-import org.apache.ibatis.session.SqlSession;
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.apache.ibatis.session.SqlSessionFactoryBuilder;
+import org.apache.ibatis.session.*;
 import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
 import org.apache.ibatis.type.JdbcType;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.BatchComponent;
 import org.sonar.api.ServerComponent;
-import org.sonar.api.database.model.MeasureMapper;
 import org.sonar.api.database.model.MeasureModel;
 import org.sonar.core.cluster.WorkQueue;
 import org.sonar.core.component.ComponentDto;
 import org.sonar.core.component.db.ComponentMapper;
 import org.sonar.core.config.Logback;
-import org.sonar.core.dashboard.ActiveDashboardDto;
-import org.sonar.core.dashboard.ActiveDashboardMapper;
-import org.sonar.core.dashboard.DashboardDto;
-import org.sonar.core.dashboard.DashboardMapper;
-import org.sonar.core.dashboard.WidgetDto;
-import org.sonar.core.dashboard.WidgetMapper;
-import org.sonar.core.dashboard.WidgetPropertyDto;
-import org.sonar.core.dashboard.WidgetPropertyMapper;
+import org.sonar.core.dashboard.*;
 import org.sonar.core.dependency.DependencyDto;
 import org.sonar.core.dependency.DependencyMapper;
 import org.sonar.core.dependency.ResourceSnapshotDto;
@@ -56,52 +44,21 @@ import org.sonar.core.duplication.DuplicationMapper;
 import org.sonar.core.duplication.DuplicationUnitDto;
 import org.sonar.core.graph.jdbc.GraphDto;
 import org.sonar.core.graph.jdbc.GraphDtoMapper;
-import org.sonar.core.issue.db.ActionPlanDto;
-import org.sonar.core.issue.db.ActionPlanMapper;
-import org.sonar.core.issue.db.ActionPlanStatsDto;
-import org.sonar.core.issue.db.ActionPlanStatsMapper;
-import org.sonar.core.issue.db.IssueChangeDto;
-import org.sonar.core.issue.db.IssueChangeMapper;
-import org.sonar.core.issue.db.IssueDto;
-import org.sonar.core.issue.db.IssueFilterDto;
-import org.sonar.core.issue.db.IssueFilterFavouriteDto;
-import org.sonar.core.issue.db.IssueFilterFavouriteMapper;
-import org.sonar.core.issue.db.IssueFilterMapper;
-import org.sonar.core.issue.db.IssueMapper;
-import org.sonar.core.issue.db.IssueStatsMapper;
-import org.sonar.core.measure.db.MeasureDataDto;
-import org.sonar.core.measure.db.MeasureDataMapper;
+import org.sonar.core.issue.db.*;
+import org.sonar.core.measure.db.MeasureDto;
 import org.sonar.core.measure.db.MeasureFilterDto;
 import org.sonar.core.measure.db.MeasureFilterMapper;
+import org.sonar.core.measure.db.MeasureMapper;
 import org.sonar.core.notification.db.NotificationQueueDto;
 import org.sonar.core.notification.db.NotificationQueueMapper;
-import org.sonar.core.permission.GroupWithPermissionDto;
-import org.sonar.core.permission.PermissionTemplateDto;
-import org.sonar.core.permission.PermissionTemplateGroupDto;
-import org.sonar.core.permission.PermissionTemplateMapper;
-import org.sonar.core.permission.PermissionTemplateUserDto;
-import org.sonar.core.permission.UserWithPermissionDto;
+import org.sonar.core.permission.*;
 import org.sonar.core.properties.PropertiesMapper;
 import org.sonar.core.properties.PropertyDto;
 import org.sonar.core.purge.PurgeMapper;
 import org.sonar.core.purge.PurgeableSnapshotDto;
-import org.sonar.core.qualitygate.db.ProjectQgateAssociationDto;
-import org.sonar.core.qualitygate.db.ProjectQgateAssociationMapper;
-import org.sonar.core.qualitygate.db.QualityGateConditionDto;
-import org.sonar.core.qualitygate.db.QualityGateConditionMapper;
-import org.sonar.core.qualitygate.db.QualityGateDto;
-import org.sonar.core.qualitygate.db.QualityGateMapper;
-import org.sonar.core.qualityprofile.db.ActiveRuleDto;
-import org.sonar.core.qualityprofile.db.ActiveRuleMapper;
-import org.sonar.core.qualityprofile.db.ActiveRuleParamDto;
-import org.sonar.core.qualityprofile.db.QualityProfileDto;
-import org.sonar.core.qualityprofile.db.QualityProfileMapper;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceIndexDto;
-import org.sonar.core.resource.ResourceIndexerMapper;
-import org.sonar.core.resource.ResourceKeyUpdaterMapper;
-import org.sonar.core.resource.ResourceMapper;
-import org.sonar.core.resource.SnapshotDto;
+import org.sonar.core.qualitygate.db.*;
+import org.sonar.core.qualityprofile.db.*;
+import org.sonar.core.resource.*;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.core.rule.RuleMapper;
 import org.sonar.core.rule.RuleParamDto;
@@ -114,16 +71,7 @@ import org.sonar.core.technicaldebt.db.RequirementDto;
 import org.sonar.core.technicaldebt.db.RequirementMapper;
 import org.sonar.core.template.LoadedTemplateDto;
 import org.sonar.core.template.LoadedTemplateMapper;
-import org.sonar.core.user.AuthorDto;
-import org.sonar.core.user.AuthorMapper;
-import org.sonar.core.user.GroupDto;
-import org.sonar.core.user.GroupMembershipDto;
-import org.sonar.core.user.GroupMembershipMapper;
-import org.sonar.core.user.GroupRoleDto;
-import org.sonar.core.user.RoleMapper;
-import org.sonar.core.user.UserDto;
-import org.sonar.core.user.UserMapper;
-import org.sonar.core.user.UserRoleDto;
+import org.sonar.core.user.*;
 
 import java.io.InputStream;
 
@@ -183,7 +131,7 @@ public class MyBatis implements BatchComponent, ServerComponent {
     loadAlias(conf, "Widget", WidgetDto.class);
     loadAlias(conf, "WidgetProperty", WidgetPropertyDto.class);
     loadAlias(conf, "MeasureModel", MeasureModel.class);
-    loadAlias(conf, "MeasureData", MeasureDataDto.class);
+    loadAlias(conf, "Measure", MeasureDto.class);
     loadAlias(conf, "Issue", IssueDto.class);
     loadAlias(conf, "IssueChange", IssueChangeDto.class);
     loadAlias(conf, "IssueFilter", IssueFilterDto.class);
@@ -214,10 +162,10 @@ public class MyBatis implements BatchComponent, ServerComponent {
       LoadedTemplateMapper.class, MeasureFilterMapper.class, PermissionTemplateMapper.class, PropertiesMapper.class, PurgeMapper.class,
       ResourceKeyUpdaterMapper.class, ResourceIndexerMapper.class, ResourceSnapshotMapper.class, RoleMapper.class, RuleMapper.class,
       SchemaMigrationMapper.class, SemaphoreMapper.class, UserMapper.class, WidgetMapper.class, WidgetPropertyMapper.class,
-      MeasureMapper.class, SnapshotDataMapper.class, SnapshotSourceMapper.class, ActionPlanMapper.class, ActionPlanStatsMapper.class,
+      org.sonar.api.database.model.MeasureMapper.class, SnapshotDataMapper.class, SnapshotSourceMapper.class, ActionPlanMapper.class, ActionPlanStatsMapper.class,
       NotificationQueueMapper.class, CharacteristicMapper.class,
       GroupMembershipMapper.class, QualityProfileMapper.class, ActiveRuleMapper.class,
-      MeasureDataMapper.class, QualityGateMapper.class, QualityGateConditionMapper.class, ComponentMapper.class, ProjectQgateAssociationMapper.class,
+      MeasureMapper.class, QualityGateMapper.class, QualityGateConditionMapper.class, ComponentMapper.class, ProjectQgateAssociationMapper.class,
       RequirementMapper.class
     };
     loadMappers(conf, mappers);
diff --git a/sonar-core/src/main/resources/org/sonar/core/measure/db/MeasureDataMapper.xml b/sonar-core/src/main/resources/org/sonar/core/measure/db/MeasureDataMapper.xml
deleted file mode 100644 (file)
index 9221a58..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-
-<mapper namespace="org.sonar.core.measure.db.MeasureDataMapper">
-
-  <sql id="measureDataColumns">
-    pm.id,
-    pm.snapshot_id as snapshotId,
-    pm.text_value as textValue,
-    pm.measure_data as data
-  </sql>
-
-  <select id="findByComponentKeyAndMetricKey" parameterType="map" resultType="MeasureData">
-    SELECT
-    <include refid="measureDataColumns"/>
-    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}
-    </where>
-  </select>
-
-</mapper>
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
new file mode 100644 (file)
index 0000000..e477036
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="org.sonar.core.measure.db.MeasureMapper">
+
+  <sql id="measureColumns">
+    pm.id,
+    pm.snapshot_id as snapshotId,
+    pm.value as value,
+    pm.text_value as textValue,
+    pm.measure_data as data
+  </sql>
+
+  <select id="findByComponentKeyAndMetricKey" 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 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 pm.rule_id IS NULL
+      AND pm.characteristic_id IS NULL
+      AND pm.person_id IS NULL
+    </where>
+  </select>
+
+</mapper>
index 7fd150b36085a362b58e892f248638a1f1508399..631497985f66274eb0aefc62da8fbd359ca8eaa3 100644 (file)
@@ -178,6 +178,18 @@ public class DefaultI18nTest {
     assertThat(manager.formatDate(Locale.ENGLISH, DateUtils.parseDateTime("2014-01-22T19:10:03+0100"))).isEqualTo("Jan 22, 2014");
   }
 
+  @Test
+  public void format_double() {
+    assertThat(manager.formatDouble(Locale.FRENCH, 10.56)).isEqualTo("10,6");
+    assertThat(manager.formatDouble(Locale.FRENCH, 10d)).isEqualTo("10,0");
+  }
+
+  @Test
+  public void format_integer() {
+    assertThat(manager.formatInteger(Locale.ENGLISH, 10)).isEqualTo("10");
+    assertThat(manager.formatInteger(Locale.ENGLISH, 100000)).isEqualTo("100,000");
+  }
+
   static URLClassLoader newCheckstyleClassloader() {
     return newClassLoader("/org/sonar/core/i18n/I18nClassloaderTest/");
   }
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
new file mode 100644 (file)
index 0000000..e00ccc5
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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/measure/db/MeasureDataDaoTest.java b/sonar-core/src/test/java/org/sonar/core/measure/db/MeasureDataDaoTest.java
deleted file mode 100644 (file)
index 81e3f05..0000000
+++ /dev/null
@@ -1,60 +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 MeasureDataDaoTest extends AbstractDaoTestCase {
-
-  private MeasureDataDao dao;
-
-  @Before
-  public void createDao() {
-    dao = new MeasureDataDao(getMyBatis());
-  }
-
-  @Test
-  public void find_data_by_component_key_and_metric_key() throws Exception {
-    setupData("shared");
-
-    MeasureDataDto result = dao.findByComponentKeyAndMetricKey("org.sonar.core.measure.db.MeasureData", "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");
-
-    MeasureDataDto result = dao.findByComponentKeyAndMetricKey("org.sonar.core.measure.db.MeasureData", "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/resources/org/sonar/core/measure/db/MeasureDaoTest/shared.xml b/sonar-core/src/test/resources/org/sonar/core/measure/db/MeasureDaoTest/shared.xml
new file mode 100644 (file)
index 0000000..70097c0
--- /dev/null
@@ -0,0 +1,15 @@
+<dataset>
+
+  <metrics id="10" name="authors_by_line"/>
+  <metrics id="11" name="coverage_line_hits_data"/>
+  <metrics id="12" name="ncloc"/>
+
+  <projects id="1" kee="org.struts:struts-core:src/org/struts/RequestContext.java" enabled="[true]"/>
+
+  <snapshots id="5" project_id="1" islast="[true]" />
+
+  <project_measures id="20" snapshot_id="5" metric_id="10" value="[null]" text_value="[null]" measure_data="MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQ=="/>
+  <project_measures id="21" snapshot_id="5" metric_id="11" value="[null]" text_value="36=1;37=1;38=1;39=1;43=1;48=1;53=1" measure_data="[null]"/>
+  <project_measures id="22" snapshot_id="5" metric_id="12" value="10" text_value="[null]" measure_data="[null]"/>
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/measure/db/MeasureDataDaoTest/shared.xml b/sonar-core/src/test/resources/org/sonar/core/measure/db/MeasureDataDaoTest/shared.xml
deleted file mode 100644 (file)
index 4c5b08e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<dataset>
-
-  <metrics id="10" name="authors_by_line"/>
-  <metrics id="11" name="coverage_line_hits_data"/>
-
-  <projects id="1" kee="org.sonar.core.measure.db.MeasureData" enabled="[true]"/>
-
-  <snapshots id="5" project_id="1" islast="[true]" />
-
-  <project_measures id="20" snapshot_id="5" metric_id="10" text_value="[null]" measure_data="MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQ=="/>
-  <project_measures id="21" snapshot_id="5" metric_id="11" text_value="36=1;37=1;38=1;39=1;43=1;48=1;53=1" measure_data="[null]"/>
-
-</dataset>
index cef56a58201dad7af8a625148c3c2812c55b06a0..3cc0936c0990153cf66d4b88e35846a74c0ee7a4 100644 (file)
@@ -102,4 +102,22 @@ public interface I18n extends ServerComponent, BatchComponent {
    */
   String formatDate(Locale locale, Date date);
 
+  /**
+   * Return the formatted decimal, with always one fraction digit.
+   * <br>
+   * Example : formatDouble(Locale.FRENCH, 10.56) -> 10,6
+   *
+   * @since 4.4
+   */
+  String formatDouble(Locale locale, Double value);
+
+  /**
+   * Return the formatted integer.
+   * <br>
+   * Example : formatInteger(Locale.ENGLISH, 100000) -> 100,000
+   *
+   * @since 4.4
+   */
+  String formatInteger(Locale locale, Integer value);
+
 }
index 538fd564b60ae3e71ab0ca7afa798bbd829d165c..8fc426d1daf942015c986648f91656d28e0f412a 100644 (file)
@@ -22,13 +22,19 @@ package org.sonar.server.component.ws;
 
 import com.google.common.io.Resources;
 import org.sonar.api.component.Component;
+import org.sonar.api.i18n.I18n;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Metric;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.RequestHandler;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
+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.properties.PropertiesDao;
 import org.sonar.core.properties.PropertyDto;
 import org.sonar.core.properties.PropertyQuery;
@@ -46,11 +52,17 @@ public class ComponentAppAction implements RequestHandler {
   private static final String KEY = "key";
 
   private final ResourceDao resourceDao;
+  private final MeasureDao measureDao;
   private final PropertiesDao propertiesDao;
+  private final Durations durations;
+  private final I18n i18n;
 
-  public ComponentAppAction(ResourceDao resourceDao, PropertiesDao propertiesDao) {
+  public ComponentAppAction(ResourceDao resourceDao, MeasureDao measureDao, PropertiesDao propertiesDao, Durations durations, I18n i18n) {
     this.resourceDao = resourceDao;
+    this.measureDao = measureDao;
     this.propertiesDao = propertiesDao;
+    this.durations = durations;
+    this.i18n = i18n;
   }
 
   void define(WebService.NewController controller) {
@@ -102,6 +114,19 @@ public class ComponentAppAction implements RequestHandler {
 
     json.prop("fav", isFavourite);
 
+    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));
+    json.endObject();
+
     json.endObject();
     json.close();
   }
@@ -114,12 +139,24 @@ public class ComponentAppAction implements RequestHandler {
     return null;
   }
 
-//  private Map<Integer, Integer> findDataFromComponent(String fileKey, String metricKey) {
-//    MeasureDataDto data = measuresDao.findByComponentKeyAndMetricKey(fileKey, metricKey);
-//    if (data != null) {
-//      return KeyValueFormat.parseIntInt(data.getData());
-//    }
-//    return Maps.newHashMap();
-//  }
+  @CheckForNull
+  private String formattedMeasure(String fileKey, Metric metric) {
+    MeasureDto measureDto = measureDao.findByComponentKeyAndMetricKey(fileKey, metric.getKey());
+    if (measureDto != null) {
+      Double value = measureDto.getValue();
+      if (value != null) {
+        if (metric.getType().equals(Metric.ValueType.FLOAT)) {
+          return i18n.formatDouble(UserSession.get().locale(), value);
+        } else if (metric.getType().equals(Metric.ValueType.INT)) {
+          return i18n.formatInteger(UserSession.get().locale(), value.intValue());
+        } else if (metric.getType().equals(Metric.ValueType.PERCENT)) {
+          return i18n.formatDouble(UserSession.get().locale(), value) + "%";
+        } else if (metric.getType().equals(Metric.ValueType.WORK_DUR)) {
+          return durations.format(UserSession.get().locale(), durations.create(value.longValue()), Durations.DurationFormat.SHORT);
+        }
+      }
+    }
+    return null;
+  }
 
 }
index ad116a80cf201fbe225a3b14cc24be047dc8bd79..cbab7733a55635b2a73024a0fade3dd1de694e7c 100644 (file)
@@ -23,8 +23,8 @@ 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.MeasureDataDao;
-import org.sonar.core.measure.db.MeasureDataDto;
+import org.sonar.core.measure.db.MeasureDao;
+import org.sonar.core.measure.db.MeasureDto;
 import org.sonar.server.user.UserSession;
 
 import javax.annotation.CheckForNull;
@@ -41,12 +41,12 @@ public class SourceService implements ServerComponent {
    */
   private final DeprecatedSourceDecorator deprecatedSourceDecorator;
 
-  private final MeasureDataDao measureDataDao;
+  private final MeasureDao measureDao;
 
-  public SourceService(HtmlSourceDecorator sourceDecorator, DeprecatedSourceDecorator deprecatedSourceDecorator, MeasureDataDao measureDataDao) {
+  public SourceService(HtmlSourceDecorator sourceDecorator, DeprecatedSourceDecorator deprecatedSourceDecorator, MeasureDao measureDao) {
     this.sourceDecorator = sourceDecorator;
     this.deprecatedSourceDecorator = deprecatedSourceDecorator;
-    this.measureDataDao = measureDataDao;
+    this.measureDao = measureDao;
   }
 
   public List<String> getLinesAsHtml(String fileKey) {
@@ -85,7 +85,7 @@ public class SourceService implements ServerComponent {
 
   @CheckForNull
   private String findDataFromComponent(String fileKey, String metricKey) {
-    MeasureDataDto data = measureDataDao.findByComponentKeyAndMetricKey(fileKey, metricKey);
+    MeasureDto data = measureDao.findByComponentKeyAndMetricKey(fileKey, metricKey);
     if (data != null) {
       return data.getData();
     }
index 7a723a8e2acdf1455865c676b5776651dbcd47cc..28ac0299002df329b21f204aaad2ed83774d1373 100644 (file)
@@ -28,8 +28,8 @@ 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.MeasureDataDao;
-import org.sonar.core.measure.db.MeasureDataDto;
+import org.sonar.core.measure.db.MeasureDao;
+import org.sonar.core.measure.db.MeasureDto;
 import org.sonar.server.user.UserSession;
 
 import javax.annotation.CheckForNull;
@@ -42,11 +42,11 @@ public class CoverageService implements ServerComponent {
     UT, IT, OVERALL
   }
 
-  private final MeasureDataDao measureDataDao;
+  private final MeasureDao measureDao;
   private final SnapshotPerspectives snapshotPerspectives;
 
-  public CoverageService(MeasureDataDao measureDataDao, SnapshotPerspectives snapshotPerspectives) {
-    this.measureDataDao = measureDataDao;
+  public CoverageService(MeasureDao measureDao, SnapshotPerspectives snapshotPerspectives) {
+    this.measureDao = measureDao;
     this.snapshotPerspectives = snapshotPerspectives;
   }
 
@@ -102,7 +102,7 @@ public class CoverageService implements ServerComponent {
 
   @CheckForNull
   private Map<Integer, Integer> findDataFromComponent(String fileKey, String metricKey) {
-    MeasureDataDto data = measureDataDao.findByComponentKeyAndMetricKey(fileKey, metricKey);
+    MeasureDto data = measureDao.findByComponentKeyAndMetricKey(fileKey, metricKey);
     if (data != null) {
       return KeyValueFormat.parseIntInt(data.getData());
     }
index ce23f709b88c39297595c890d3e2975a57e5ef66..edb029da2920c26a6dd7174ebe941d77fcfac9d4 100644 (file)
@@ -8,12 +8,15 @@
   "fav": true,
   "periods": [],
   "measures": {
-    "ncloc": 200,
-    "coverage": 2,
-    "duplication_density": 1,
-    "debt": 1,
-    "issues": 1,
-    "blocker_issues": 1,
-    "info_issues": 1
+    "fNcloc": "200",
+    "fCoverage": "95.4%",
+    "fDuplicationDensity": "7.4%",
+    "fDebt": "3d 2h",
+    "fIssues": "14",
+    "fBlockerIssues": "1",
+    "fCriticalIssues": "2",
+    "fMajorIssues": "5",
+    "fMinorIssues": "4",
+    "fInfoIssues": "2"
   }
 }
index a333bf7f6217247878b709cc30cc75a9e6c894e3..4dbbcb53cafd17fd0f3968e88c0bb5a2487bb726 100644 (file)
@@ -25,8 +25,14 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.sonar.api.i18n.I18n;
+import org.sonar.api.measures.CoreMetrics;
+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.properties.PropertiesDao;
 import org.sonar.core.properties.PropertyDto;
 import org.sonar.core.properties.PropertyQuery;
@@ -34,41 +40,77 @@ import org.sonar.core.resource.ResourceDao;
 import org.sonar.server.user.MockUserSession;
 import org.sonar.server.ws.WsTester;
 
+import java.util.Locale;
+
 import static com.google.common.collect.Lists.newArrayList;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.when;
 
 @RunWith(MockitoJUnitRunner.class)
 public class ComponentAppActionTest {
 
+  static final String PROJECT_KEY = "org.codehaus.sonar:sonar-plugin-api:api";
+  static final String COMPONENT_KEY = "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java";
+
   @Mock
   ResourceDao resourceDao;
 
+  @Mock
+  MeasureDao measureDao;
+
   @Mock
   PropertiesDao propertiesDao;
 
+  @Mock
+  Durations durations;
+
+  @Mock
+  I18n i18n;
+
   WsTester tester;
 
   @Before
   public void setUp() throws Exception {
-    tester = new WsTester(new ComponentsWs(new ComponentAppAction(resourceDao, propertiesDao)));
+    tester = new WsTester(new ComponentsWs(new ComponentAppAction(resourceDao, measureDao, propertiesDao, durations, i18n)));
   }
 
   @Test
   public void app() throws Exception {
-    String projectKey = "org.codehaus.sonar:sonar-plugin-api:api";
-    String componentKey = "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java";
-    MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, projectKey).addComponent(componentKey, projectKey);
+    MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, PROJECT_KEY).addComponent(COMPONENT_KEY, PROJECT_KEY);
 
-    ComponentDto file = new ComponentDto().setId(10L).setQualifier("FIL").setKey(componentKey).setName("Plugin.java")
+    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(componentKey)).thenReturn(file);
+    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()));
 
-    WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("key", componentKey);
+    addMeasure(CoreMetrics.NCLOC_KEY, 200);
+    addMeasure(CoreMetrics.COVERAGE_KEY, 95.4);
+    addMeasure(CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, 7.4);
+    addMeasure(CoreMetrics.VIOLATIONS_KEY, 14);
+    addMeasure(CoreMetrics.BLOCKER_VIOLATIONS_KEY, 1);
+    addMeasure(CoreMetrics.CRITICAL_VIOLATIONS_KEY, 2);
+    addMeasure(CoreMetrics.MAJOR_VIOLATIONS_KEY, 5);
+    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));
+    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);
     request.execute().assertJson(getClass(), "app.json");
   }
 
+  private void addMeasure(String metricKey, Integer value){
+    when(measureDao.findByComponentKeyAndMetricKey(COMPONENT_KEY, metricKey)).thenReturn(new MeasureDto().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));
+    when(i18n.formatDouble(any(Locale.class), eq(value))).thenReturn(Double.toString(value));
+  }
+
 }
index 2b2c548ae2a546267a604c39bb9d0b563b94bed1..14a86e4e6d44224185e82faf2182466b0404fe16 100644 (file)
@@ -22,8 +22,11 @@ package org.sonar.server.component.ws;
 
 import org.junit.Before;
 import org.junit.Test;
+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.server.ws.WsTester;
@@ -37,7 +40,8 @@ public class ComponentsWsTest {
 
   @Before
   public void setUp() throws Exception {
-    WsTester tester = new WsTester(new ComponentsWs(new ComponentAppAction(mock(ResourceDao.class), mock(PropertiesDao.class))));
+    WsTester tester = new WsTester(new ComponentsWs(new ComponentAppAction(mock(ResourceDao.class), mock(MeasureDao.class), mock(PropertiesDao.class),
+      mock(Durations.class), mock(I18n.class))));
     controller = tester.controller("api/components");
   }
 
index 88d5ed5e200086428396be3ade6b98adf06ecc99..91eca92a641f4e7a011546ba661ef300967940a3 100644 (file)
@@ -27,7 +27,7 @@ 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.MeasureDataDao;
+import org.sonar.core.measure.db.MeasureDao;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.user.MockUserSession;
 
@@ -47,13 +47,13 @@ public class SourceServiceTest {
   DeprecatedSourceDecorator deprecatedSourceDecorator;
 
   @Mock
-  MeasureDataDao measureDataDao;
+  MeasureDao measureDao;
 
   SourceService service;
 
   @Before
   public void setUp() throws Exception {
-    service = new SourceService(sourceDecorator, deprecatedSourceDecorator, measureDataDao);
+    service = new SourceService(sourceDecorator, deprecatedSourceDecorator, measureDao);
   }
 
   @Test
@@ -110,13 +110,13 @@ public class SourceServiceTest {
   public void get_scm_author_data() throws Exception {
     String componentKey = "org.sonar.sample:Sample";
     service.getScmAuthorData(componentKey);
-    verify(measureDataDao).findByComponentKeyAndMetricKey(componentKey, CoreMetrics.SCM_AUTHORS_BY_LINE_KEY);
+    verify(measureDao).findByComponentKeyAndMetricKey(componentKey, CoreMetrics.SCM_AUTHORS_BY_LINE_KEY);
   }
 
   @Test
   public void not_get_scm_author_data_if_no_data() throws Exception {
     String componentKey = "org.sonar.sample:Sample";
-    when(measureDataDao.findByComponentKeyAndMetricKey(eq(componentKey), anyString())).thenReturn(null);
+    when(measureDao.findByComponentKeyAndMetricKey(eq(componentKey), anyString())).thenReturn(null);
     assertThat(service.getScmAuthorData(componentKey)).isNull();
   }
 
@@ -124,13 +124,13 @@ public class SourceServiceTest {
   public void get_scm_date_data() throws Exception {
     String componentKey = "org.sonar.sample:Sample";
     service.getScmDateData(componentKey);
-    verify(measureDataDao).findByComponentKeyAndMetricKey(componentKey, CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE_KEY);
+    verify(measureDao).findByComponentKeyAndMetricKey(componentKey, CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE_KEY);
   }
 
   @Test
   public void not_get_scm_date_data_if_no_data() throws Exception {
     String componentKey = "org.sonar.sample:Sample";
-    when(measureDataDao.findByComponentKeyAndMetricKey(eq(componentKey), anyString())).thenReturn(null);
+    when(measureDao.findByComponentKeyAndMetricKey(eq(componentKey), anyString())).thenReturn(null);
     assertThat(service.getScmDateData(componentKey)).isNull();
   }
 }
index 9a158755c59b3471eec58d59d015a278a6660dde..4d033dd383b49f0c5da341c747e281653d142427 100644 (file)
@@ -30,7 +30,7 @@ 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.MeasureDataDao;
+import org.sonar.core.measure.db.MeasureDao;
 import org.sonar.server.user.MockUserSession;
 
 import java.util.Collections;
@@ -47,7 +47,7 @@ public class CoverageServiceTest {
   public ExpectedException thrown = ExpectedException.none();
 
   @Mock
-  MeasureDataDao measureDataDao;
+  MeasureDao measureDao;
 
   @Mock
   SnapshotPerspectives snapshotPerspectives;
@@ -58,7 +58,7 @@ public class CoverageServiceTest {
 
   @Before
   public void setUp() throws Exception {
-    service = new CoverageService(measureDataDao, snapshotPerspectives);
+    service = new CoverageService(measureDao, snapshotPerspectives);
   }
 
   @Test
@@ -73,43 +73,43 @@ public class CoverageServiceTest {
   @Test
   public void get_hits_data() throws Exception {
     service.getHits(COMPONENT_KEY, CoverageService.TYPE.UT);
-    verify(measureDataDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY);
+    verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY);
 
     service.getHits(COMPONENT_KEY, CoverageService.TYPE.IT);
-    verify(measureDataDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY);
+    verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY);
 
     service.getHits(COMPONENT_KEY, CoverageService.TYPE.OVERALL);
-    verify(measureDataDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA_KEY);
+    verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA_KEY);
   }
 
   @Test
   public void not_get_hits_data_if_no_data() throws Exception {
-    when(measureDataDao.findByComponentKeyAndMetricKey(eq(COMPONENT_KEY), anyString())).thenReturn(null);
+    when(measureDao.findByComponentKeyAndMetricKey(eq(COMPONENT_KEY), anyString())).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(measureDataDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.CONDITIONS_BY_LINE_KEY);
+    verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.CONDITIONS_BY_LINE_KEY);
 
     service.getConditions(COMPONENT_KEY, CoverageService.TYPE.IT);
-    verify(measureDataDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.IT_CONDITIONS_BY_LINE_KEY);
+    verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.IT_CONDITIONS_BY_LINE_KEY);
 
     service.getConditions(COMPONENT_KEY, CoverageService.TYPE.OVERALL);
-    verify(measureDataDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.OVERALL_CONDITIONS_BY_LINE_KEY);
+    verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.OVERALL_CONDITIONS_BY_LINE_KEY);
   }
 
   @Test
   public void get_covered_conditions_data() throws Exception {
     service.getCoveredConditions(COMPONENT_KEY, CoverageService.TYPE.UT);
-    verify(measureDataDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY);
+    verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY);
 
     service.getCoveredConditions(COMPONENT_KEY, CoverageService.TYPE.IT);
-    verify(measureDataDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE_KEY);
+    verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE_KEY);
 
     service.getCoveredConditions(COMPONENT_KEY, CoverageService.TYPE.OVERALL);
-    verify(measureDataDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE_KEY);
+    verify(measureDao).findByComponentKeyAndMetricKey(COMPONENT_KEY, CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE_KEY);
   }
 
   @Test
index ff887f9a77067856e1a404cf9b66a582c6a899f1..dd9f33365b023001982cba8fe3fea8d8192b059f 100644 (file)
@@ -5,5 +5,17 @@
   "q": "FIL",
   "subProjectName": "SonarQube :: Plugin API",
   "projectName": "SonarQube",
-  "fav": true
+  "fav": true,
+  "measures": {
+    "fNcloc": "200",
+    "fCoverage": "95.4%",
+    "fDuplicationDensity": "7.4%",
+    "fDebt": "3h 2min",
+    "fIssues": "14",
+    "fBlockerIssues": "1",
+    "fCriticalIssues": "2",
+    "fMajorIssues": "5",
+    "fMinorIssues": "4",
+    "fInfoIssues": "2"
+  }
 }