aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-ws
diff options
context:
space:
mode:
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2016-01-06 17:46:38 +0100
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2016-01-13 14:13:35 +0100
commit0242e1da3fea5a96a9f0632156b1cacdd89b9ace (patch)
tree68166c8f6ed52713ba24b5d94e9fe00616491e05 /sonar-ws
parent49b3b0bc394ce675356d832e1d12459b9be543bd (diff)
downloadsonarqube-0242e1da3fea5a96a9f0632156b1cacdd89b9ace.tar.gz
sonarqube-0242e1da3fea5a96a9f0632156b1cacdd89b9ace.zip
SONAR-7135 WS api/measures/component_tree navigate through components and display measures
Diffstat (limited to 'sonar-ws')
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/BaseService.java11
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/HttpWsClient.java8
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java3
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java2
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesService.java58
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/measure/ComponentTreeWsRequest.java160
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresService.java59
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresWsParameters.java42
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/measure/package-info.java26
-rw-r--r--sonar-ws/src/main/protobuf/ws-commons.proto15
-rw-r--r--sonar-ws/src/main/protobuf/ws-measures.proto78
-rw-r--r--sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java10
-rw-r--r--sonar-ws/src/test/java/org/sonarqube/ws/client/measure/MeasuresServiceTest.java96
13 files changed, 533 insertions, 35 deletions
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/BaseService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/BaseService.java
index e3bd7ad1aab..c8f2e816117 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/BaseService.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/BaseService.java
@@ -19,9 +19,13 @@
*/
package org.sonarqube.ws.client;
+import com.google.common.base.Joiner;
import com.google.protobuf.Message;
import com.google.protobuf.Parser;
import java.io.InputStream;
+import java.util.List;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import org.sonarqube.ws.MediaTypes;
import static com.google.common.base.Preconditions.checkArgument;
@@ -29,6 +33,8 @@ import static com.google.common.base.Strings.isNullOrEmpty;
public abstract class BaseService {
+ private static final Joiner MULTI_VALUES_JOINER = Joiner.on(",");
+
private final WsConnector wsConnector;
protected final String controller;
@@ -60,4 +66,9 @@ public abstract class BaseService {
protected String path(String action) {
return String.format("%s/%s", controller, action);
}
+
+ @CheckForNull
+ protected static String inlineMultipleParamValue(@Nullable List<String> values) {
+ return values == null ? null : MULTI_VALUES_JOINER.join(values);
+ }
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpWsClient.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpWsClient.java
index f779b9869c1..8921549e962 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpWsClient.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpWsClient.java
@@ -21,6 +21,7 @@ package org.sonarqube.ws.client;
import org.sonarqube.ws.client.component.ComponentsService;
import org.sonarqube.ws.client.issue.IssuesService;
+import org.sonarqube.ws.client.measure.MeasuresService;
import org.sonarqube.ws.client.permission.PermissionsService;
import org.sonarqube.ws.client.qualitygate.QualityGatesService;
import org.sonarqube.ws.client.qualityprofile.QualityProfilesService;
@@ -39,6 +40,7 @@ public class HttpWsClient implements WsClient {
private final IssuesService issuesService;
private final UserTokensService userTokensService;
private final QualityGatesService qualityGatesService;
+ private final MeasuresService measuresService;
private final WsConnector wsConnector;
public HttpWsClient(WsConnector wsConnector) {
@@ -49,6 +51,7 @@ public class HttpWsClient implements WsClient {
this.issuesService = new IssuesService(wsConnector);
this.userTokensService = new UserTokensService(wsConnector);
this.qualityGatesService = new QualityGatesService(wsConnector);
+ this.measuresService = new MeasuresService(wsConnector);
}
@Override
@@ -85,4 +88,9 @@ public class HttpWsClient implements WsClient {
public QualityGatesService qualityGates() {
return qualityGatesService;
}
+
+ @Override
+ public MeasuresService measures() {
+ return measuresService;
+ }
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java
index a6329005864..e833c20f1d1 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java
@@ -21,6 +21,7 @@ package org.sonarqube.ws.client;
import org.sonarqube.ws.client.component.ComponentsService;
import org.sonarqube.ws.client.issue.IssuesService;
+import org.sonarqube.ws.client.measure.MeasuresService;
import org.sonarqube.ws.client.permission.PermissionsService;
import org.sonarqube.ws.client.qualitygate.QualityGatesService;
import org.sonarqube.ws.client.qualityprofile.QualityProfilesService;
@@ -42,5 +43,7 @@ public interface WsClient {
QualityGatesService qualityGates();
+ MeasuresService measures();
+
WsConnector wsConnector();
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java
index 95dac85cb66..3188123e551 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java
@@ -55,7 +55,7 @@ public class ComponentsService extends BaseService {
GetRequest get = new GetRequest(path(ACTION_TREE))
.setParam(PARAM_BASE_COMPONENT_ID, request.getBaseComponentId())
.setParam(PARAM_BASE_COMPONENT_KEY, request.getBaseComponentKey())
- .setParam(PARAM_QUALIFIERS, request.getQualifiers())
+ .setParam(PARAM_QUALIFIERS, inlineMultipleParamValue(request.getQualifiers()))
.setParam(PARAM_STRATEGY, request.getStrategy())
.setParam("p", request.getPage())
.setParam("ps", request.getPageSize())
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesService.java
index 945174c838f..dbd2f1f60e6 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesService.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesService.java
@@ -20,9 +20,6 @@
package org.sonarqube.ws.client.issue;
import com.google.common.base.Joiner;
-import java.util.List;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
import org.sonarqube.ws.Issues.SearchWsResponse;
import org.sonarqube.ws.client.BaseService;
import org.sonarqube.ws.client.GetRequest;
@@ -72,50 +69,43 @@ public class IssuesService extends BaseService {
public SearchWsResponse search(SearchWsRequest request) {
return call(
new GetRequest(path("search"))
- .setParam(ACTION_PLANS, listToParamList(request.getActionPlans()))
- .setParam(ADDITIONAL_FIELDS, listToParamList(request.getAdditionalFields()))
+ .setParam(ACTION_PLANS, inlineMultipleParamValue(request.getActionPlans()))
+ .setParam(ADDITIONAL_FIELDS, inlineMultipleParamValue(request.getAdditionalFields()))
.setParam(ASC, request.getAsc())
.setParam(ASSIGNED, request.getAssigned())
- .setParam(ASSIGNEES, listToParamList(request.getAssignees()))
- .setParam(AUTHORS, listToParamList(request.getAuthors()))
- .setParam(COMPONENT_KEYS, listToParamList(request.getComponentKeys()))
- .setParam(COMPONENT_ROOT_UUIDS, listToParamList(request.getComponentRootUuids()))
- .setParam(COMPONENT_ROOTS, listToParamList(request.getComponentRoots()))
- .setParam(COMPONENT_UUIDS, listToParamList(request.getComponentUuids()))
- .setParam(COMPONENTS, listToParamList(request.getComponents()))
+ .setParam(ASSIGNEES, inlineMultipleParamValue(request.getAssignees()))
+ .setParam(AUTHORS, inlineMultipleParamValue(request.getAuthors()))
+ .setParam(COMPONENT_KEYS, inlineMultipleParamValue(request.getComponentKeys()))
+ .setParam(COMPONENT_ROOT_UUIDS, inlineMultipleParamValue(request.getComponentRootUuids()))
+ .setParam(COMPONENT_ROOTS, inlineMultipleParamValue(request.getComponentRoots()))
+ .setParam(COMPONENT_UUIDS, inlineMultipleParamValue(request.getComponentUuids()))
+ .setParam(COMPONENTS, inlineMultipleParamValue(request.getComponents()))
.setParam(CREATED_AFTER, request.getCreatedAfter())
.setParam(CREATED_AT, request.getCreatedAt())
.setParam(CREATED_BEFORE, request.getCreatedBefore())
.setParam(CREATED_IN_LAST, request.getCreatedInLast())
- .setParam(DIRECTORIES, listToParamList(request.getDirectories()))
+ .setParam(DIRECTORIES, inlineMultipleParamValue(request.getDirectories()))
.setParam(FACET_MODE, request.getFacetMode())
- .setParam("facets", listToParamList(request.getFacets()))
- .setParam(FILE_UUIDS, listToParamList(request.getFileUuids()))
- .setParam(ISSUES, listToParamList(request.getIssues()))
- .setParam(LANGUAGES, listToParamList(request.getLanguages()))
- .setParam(MODULE_UUIDS, listToParamList(request.getModuleUuids()))
+ .setParam("facets", inlineMultipleParamValue(request.getFacets()))
+ .setParam(FILE_UUIDS, inlineMultipleParamValue(request.getFileUuids()))
+ .setParam(ISSUES, inlineMultipleParamValue(request.getIssues()))
+ .setParam(LANGUAGES, inlineMultipleParamValue(request.getLanguages()))
+ .setParam(MODULE_UUIDS, inlineMultipleParamValue(request.getModuleUuids()))
.setParam(ON_COMPONENT_ONLY, request.getOnComponentOnly())
.setParam("p", request.getPage())
.setParam("ps", request.getPageSize())
.setParam(PLANNED, request.getPlanned())
- .setParam(PROJECT_KEYS, listToParamList(request.getProjectKeys()))
- .setParam(PROJECT_UUIDS, listToParamList(request.getProjectUuids()))
- .setParam(PROJECTS, listToParamList(request.getProjects()))
- .setParam(REPORTERS, listToParamList(request.getReporters()))
- .setParam(RESOLUTIONS, listToParamList(request.getResolutions()))
+ .setParam(PROJECT_KEYS, inlineMultipleParamValue(request.getProjectKeys()))
+ .setParam(PROJECT_UUIDS, inlineMultipleParamValue(request.getProjectUuids()))
+ .setParam(PROJECTS, inlineMultipleParamValue(request.getProjects()))
+ .setParam(REPORTERS, inlineMultipleParamValue(request.getReporters()))
+ .setParam(RESOLUTIONS, inlineMultipleParamValue(request.getResolutions()))
.setParam(RESOLVED, request.getResolved())
- .setParam(RULES, listToParamList(request.getRules()))
+ .setParam(RULES, inlineMultipleParamValue(request.getRules()))
.setParam("s", request.getSort())
- .setParam(SEVERITIES, listToParamList(request.getSeverities()))
- .setParam(STATUSES, listToParamList(request.getStatuses()))
- .setParam(TAGS, listToParamList(request.getTags())),
+ .setParam(SEVERITIES, inlineMultipleParamValue(request.getSeverities()))
+ .setParam(STATUSES, inlineMultipleParamValue(request.getStatuses()))
+ .setParam(TAGS, inlineMultipleParamValue(request.getTags())),
SearchWsResponse.parser());
}
-
- @CheckForNull
- private static String listToParamList(@Nullable List<String> strings) {
- return strings == null
- ? null
- : LIST_TO_PARAMS_STRING.join(strings);
- }
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/ComponentTreeWsRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/ComponentTreeWsRequest.java
new file mode 100644
index 00000000000..2519f13e436
--- /dev/null
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/ComponentTreeWsRequest.java
@@ -0,0 +1,160 @@
+/*
+ * SonarQube :: Web Service
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.sonarqube.ws.client.measure;
+
+import java.util.List;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+public class ComponentTreeWsRequest {
+
+ private String baseComponentId;
+ private String baseComponentKey;
+ private String strategy;
+ private List<String> qualifiers;
+ private List<String> additionalFields;
+ private String query;
+ private List<String> sort;
+ private Boolean asc;
+ private String metricSort;
+ private List<String> metricKeys;
+ private Integer page;
+ private Integer pageSize;
+
+ @CheckForNull
+ public String getBaseComponentId() {
+ return baseComponentId;
+ }
+
+ public ComponentTreeWsRequest setBaseComponentId(@Nullable String baseComponentId) {
+ this.baseComponentId = baseComponentId;
+ return this;
+ }
+
+ @CheckForNull
+ public String getBaseComponentKey() {
+ return baseComponentKey;
+ }
+
+ public ComponentTreeWsRequest setBaseComponentKey(@Nullable String baseComponentKey) {
+ this.baseComponentKey = baseComponentKey;
+ return this;
+ }
+
+ @CheckForNull
+ public String getStrategy() {
+ return strategy;
+ }
+
+ public ComponentTreeWsRequest setStrategy(String strategy) {
+ this.strategy = strategy;
+ return this;
+ }
+
+ @CheckForNull
+ public List<String> getQualifiers() {
+ return qualifiers;
+ }
+
+ public ComponentTreeWsRequest setQualifiers(@Nullable List<String> qualifiers) {
+ this.qualifiers = qualifiers;
+ return this;
+ }
+
+ @CheckForNull
+ public List<String> getAdditionalFields() {
+ return additionalFields;
+ }
+
+ public ComponentTreeWsRequest setAdditionalFields(@Nullable List<String> additionalFields) {
+ this.additionalFields = additionalFields;
+ return this;
+ }
+
+ @CheckForNull
+ public String getQuery() {
+ return query;
+ }
+
+ public ComponentTreeWsRequest setQuery(@Nullable String query) {
+ this.query = query;
+ return this;
+ }
+
+ @CheckForNull
+ public List<String> getSort() {
+ return sort;
+ }
+
+ public ComponentTreeWsRequest setSort(@Nullable List<String> sort) {
+ this.sort = sort;
+ return this;
+ }
+
+ @CheckForNull
+ public String getMetricSort() {
+ return metricSort;
+ }
+
+ public ComponentTreeWsRequest setMetricSort(@Nullable String metricSort) {
+ this.metricSort = metricSort;
+ return this;
+ }
+
+ @CheckForNull
+ public List<String> getMetricKeys() {
+ return metricKeys;
+ }
+
+ public ComponentTreeWsRequest setMetricKeys(List<String> metricKeys) {
+ this.metricKeys = metricKeys;
+ return this;
+ }
+
+ @CheckForNull
+ public Boolean getAsc() {
+ return asc;
+ }
+
+ public ComponentTreeWsRequest setAsc(boolean asc) {
+ this.asc = asc;
+ return this;
+ }
+
+ @CheckForNull
+ public Integer getPage() {
+ return page;
+ }
+
+ public ComponentTreeWsRequest setPage(int page) {
+ this.page = page;
+ return this;
+ }
+
+ @CheckForNull
+ public Integer getPageSize() {
+ return pageSize;
+ }
+
+ public ComponentTreeWsRequest setPageSize(int pageSize) {
+ this.pageSize = pageSize;
+ return this;
+ }
+}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresService.java
new file mode 100644
index 00000000000..3e34aacdf8d
--- /dev/null
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresService.java
@@ -0,0 +1,59 @@
+/*
+ * SonarQube :: Web Service
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.sonarqube.ws.client.measure;
+
+import org.sonarqube.ws.WsMeasures;
+import org.sonarqube.ws.client.BaseService;
+import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.WsConnector;
+
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.ACTION_COMPONENT_TREE;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.CONTROLLER_MEASURES;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_ADDITIONAL_FIELDS;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BASE_COMPONENT_ID;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BASE_COMPONENT_KEY;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_KEYS;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_SORT;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_QUALIFIERS;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_STRATEGY;
+
+public class MeasuresService extends BaseService {
+ public MeasuresService(WsConnector wsConnector) {
+ super(wsConnector, CONTROLLER_MEASURES);
+ }
+
+ public WsMeasures.ComponentTreeWsResponse componentTree(ComponentTreeWsRequest request) {
+ GetRequest getRequest = new GetRequest(path(ACTION_COMPONENT_TREE))
+ .setParam(PARAM_BASE_COMPONENT_ID, request.getBaseComponentId())
+ .setParam(PARAM_BASE_COMPONENT_KEY, request.getBaseComponentKey())
+ .setParam(PARAM_STRATEGY, request.getStrategy())
+ .setParam(PARAM_QUALIFIERS, inlineMultipleParamValue(request.getQualifiers()))
+ .setParam(PARAM_METRIC_KEYS, inlineMultipleParamValue(request.getMetricKeys()))
+ .setParam(PARAM_ADDITIONAL_FIELDS, inlineMultipleParamValue(request.getAdditionalFields()))
+ .setParam("q", request.getQuery())
+ .setParam("p", request.getPage())
+ .setParam("ps", request.getPageSize())
+ .setParam("s", inlineMultipleParamValue(request.getSort()))
+ .setParam("asc", request.getAsc())
+ .setParam(PARAM_METRIC_SORT, request.getMetricSort());
+
+ return call(getRequest, WsMeasures.ComponentTreeWsResponse.parser());
+ }
+}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresWsParameters.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresWsParameters.java
new file mode 100644
index 00000000000..fdc58f60e69
--- /dev/null
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresWsParameters.java
@@ -0,0 +1,42 @@
+/*
+ * SonarQube :: Web Service
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.sonarqube.ws.client.measure;
+
+public class MeasuresWsParameters {
+ private MeasuresWsParameters() {
+ // static constants only
+ }
+
+ public static final String CONTROLLER_MEASURES = "api/measures";
+
+ // actions
+ public static final String ACTION_COMPONENT_TREE = "component_tree";
+
+ // parameters
+ public static final String PARAM_BASE_COMPONENT_ID = "baseComponentId";
+ public static final String PARAM_BASE_COMPONENT_KEY = "baseComponentKey";
+ public static final String PARAM_STRATEGY = "strategy";
+ public static final String PARAM_QUALIFIERS = "qualifiers";
+ public static final String PARAM_METRIC_KEYS = "metricKeys";
+ public static final String PARAM_METRIC_SORT = "metricSort";
+ public static final String PARAM_ADDITIONAL_FIELDS = "additionalFields";
+}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/package-info.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/package-info.java
new file mode 100644
index 00000000000..09161aa4911
--- /dev/null
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * SonarQube :: Web Service
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.sonarqube.ws.client.measure;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
diff --git a/sonar-ws/src/main/protobuf/ws-commons.proto b/sonar-ws/src/main/protobuf/ws-commons.proto
index 58b57986c78..efd2fee3ca4 100644
--- a/sonar-ws/src/main/protobuf/ws-commons.proto
+++ b/sonar-ws/src/main/protobuf/ws-commons.proto
@@ -97,3 +97,18 @@ message TextRange {
// If absent it means range ends at the last offset of end line
optional int32 endOffset = 4;
}
+
+message Metric {
+ optional string key = 1;
+ optional string name = 2;
+ optional string description = 3;
+ optional string domain = 4;
+ optional string type = 5;
+ optional bool higherValuesAreBetter = 6;
+ optional bool qualitative = 7;
+ optional bool hidden = 8;
+ optional bool custom = 9;
+ optional int32 decimalScale = 10;
+ optional string bestValue = 11;
+ optional string worstValue = 12;
+}
diff --git a/sonar-ws/src/main/protobuf/ws-measures.proto b/sonar-ws/src/main/protobuf/ws-measures.proto
new file mode 100644
index 00000000000..395484609a2
--- /dev/null
+++ b/sonar-ws/src/main/protobuf/ws-measures.proto
@@ -0,0 +1,78 @@
+// SonarQube, open source software quality management tool.
+// Copyright (C) 2008-2015 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.
+
+syntax = "proto2";
+
+package sonarqube.ws.measures;
+
+import "ws-commons.proto";
+
+option java_package = "org.sonarqube.ws";
+option java_outer_classname = "WsMeasures";
+option optimize_for = SPEED;
+
+// WS api/measures/component_tree
+message ComponentTreeWsResponse {
+ optional sonarqube.ws.commons.Paging paging = 1;
+ optional Component baseComponent = 2;
+ repeated Component components = 3;
+ optional Metrics metrics = 4;
+ optional Periods periods = 5;
+}
+
+message Component {
+ optional string id = 1;
+ optional string refId = 2;
+ optional string key = 3;
+ optional string projectId = 4;
+ optional string name = 5;
+ optional string description = 6;
+ optional string qualifier = 7;
+ optional string path = 8;
+ optional string language = 9;
+ optional Measures measures = 10;
+}
+
+message Period {
+ optional int32 index = 1;
+ optional string mode = 2;
+ optional string date = 3;
+ optional string parameter = 4;
+}
+
+message Periods {
+ repeated Period periods = 1;
+}
+
+message Metrics {
+ repeated sonarqube.ws.commons.Metric metrics = 1;
+}
+
+message Measures {
+ repeated Measure measures = 1;
+}
+
+message Measure {
+ optional string metric = 1;
+ optional string value = 2;
+ optional string variationValueP1 = 3;
+ optional string variationValueP2 = 4;
+ optional string variationValueP3 = 5;
+ optional string variationValueP4 = 6;
+ optional string variationValueP5 = 7;
+}
diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java
index 3ba2e88aef4..01f0019f3b8 100644
--- a/sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java
+++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java
@@ -308,6 +308,16 @@ public class ServiceTester<T extends BaseService> extends ExternalResource {
return this;
}
+ public RequestAssert hasParam(String key, boolean value) {
+ isNotNull();
+
+ MapEntry<String, String> entry = MapEntry.entry(key, String.valueOf(value));
+ Assertions.assertThat(actual.getParams()).contains(entry);
+ this.assertedParams.add(entry);
+
+ return this;
+ }
+
public RequestAssert andNoOtherParam() {
isNotNull();
diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/measure/MeasuresServiceTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/measure/MeasuresServiceTest.java
new file mode 100644
index 00000000000..c41080a642d
--- /dev/null
+++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/measure/MeasuresServiceTest.java
@@ -0,0 +1,96 @@
+/*
+ * SonarQube :: Web Service
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.sonarqube.ws.client.measure;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonarqube.ws.WsMeasures.ComponentTreeWsResponse;
+import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.ServiceTester;
+import org.sonarqube.ws.client.WsConnector;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_ADDITIONAL_FIELDS;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BASE_COMPONENT_ID;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BASE_COMPONENT_KEY;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_KEYS;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_SORT;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_QUALIFIERS;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_STRATEGY;
+
+public class MeasuresServiceTest {
+ private static final String VALUE_BASE_COMPONENT_ID = "base-component-id";
+ private static final String VALUE_BASE_COMPONENT_KEY = "base-component-key";
+ private static final List<String> VALUE_METRIC_KEYS = newArrayList("ncloc", "complexity");
+ private static final String VALUE_STRATEGY = "all";
+ private static final List<String> VALUE_QUALIFIERS = newArrayList("FIL", "PRJ");
+ private static final ArrayList<String> VALUE_ADDITIONAL_FIELDS = newArrayList("metrics");
+ private static final List<String> VALUE_SORT = newArrayList("qualifier", "metric");
+ private static final boolean VALUE_ASC = false;
+ private static final String VALUE_METRIC_SORT = "ncloc";
+ private static final int VALUE_PAGE = 42;
+ private static final int VALUE_PAGE_SIZE = 1984;
+ private static final String VALUE_QUERY = "query-sq";
+
+ @Rule
+ public ServiceTester<MeasuresService> serviceTester = new ServiceTester<>(new MeasuresService(mock(WsConnector.class)));
+
+ private MeasuresService underTest = serviceTester.getInstanceUnderTest();
+
+ @Test
+ public void component_tree() {
+ ComponentTreeWsRequest componentTreeRequest = new ComponentTreeWsRequest()
+ .setBaseComponentId(VALUE_BASE_COMPONENT_ID)
+ .setBaseComponentKey(VALUE_BASE_COMPONENT_KEY)
+ .setMetricKeys(VALUE_METRIC_KEYS)
+ .setStrategy(VALUE_STRATEGY)
+ .setQualifiers(VALUE_QUALIFIERS)
+ .setAdditionalFields(VALUE_ADDITIONAL_FIELDS)
+ .setSort(VALUE_SORT)
+ .setAsc(VALUE_ASC)
+ .setMetricSort(VALUE_METRIC_SORT)
+ .setPage(VALUE_PAGE)
+ .setPageSize(VALUE_PAGE_SIZE)
+ .setQuery(VALUE_QUERY);
+
+ underTest.componentTree(componentTreeRequest);
+ GetRequest getRequest = serviceTester.getGetRequest();
+
+ assertThat(serviceTester.getGetParser()).isSameAs(ComponentTreeWsResponse.parser());
+ serviceTester.assertThat(getRequest)
+ .hasParam(PARAM_BASE_COMPONENT_ID, VALUE_BASE_COMPONENT_ID)
+ .hasParam(PARAM_BASE_COMPONENT_KEY, VALUE_BASE_COMPONENT_KEY)
+ .hasParam(PARAM_METRIC_KEYS, "ncloc,complexity")
+ .hasParam(PARAM_STRATEGY, VALUE_STRATEGY)
+ .hasParam(PARAM_QUALIFIERS, "FIL,PRJ")
+ .hasParam(PARAM_ADDITIONAL_FIELDS, "metrics")
+ .hasParam("s", "qualifier,metric")
+ .hasParam("asc", VALUE_ASC)
+ .hasParam(PARAM_METRIC_SORT, VALUE_METRIC_SORT)
+ .hasParam("p", VALUE_PAGE)
+ .hasParam("ps", VALUE_PAGE_SIZE)
+ .hasParam("q", VALUE_QUERY)
+ .andNoOtherParam();
+ }
+}