import static org.sonar.db.component.ComponentKeyUpdaterDao.checkIsProjectOrModule;
import static org.sonar.server.ws.WsUtils.checkRequest;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_BULK_UPDATE_KEY;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_DRY_RUN;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FROM;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ID;
@Override
public void define(WebService.NewController context) {
- WebService.NewAction action = context.createAction("bulk_update_key")
+ WebService.NewAction action = context.createAction(ACTION_BULK_UPDATE_KEY)
.setDescription("Bulk update a project or module key and all its sub-components keys. " +
"The bulk update allows to replace a part of the current key by another string on the current project and all its sub-modules.<br>" +
"It's possible to simulate the bulk update by setting the parameter '%s' at true. No key is updated with a dry run.<br>" +
import org.sonar.api.server.ws.RailsHandler;
import org.sonar.api.server.ws.WebService;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.CONTROLLER_COMPONENTS;
+
public class ComponentsWs implements WebService {
private final AppAction appAction;
@Override
public void define(Context context) {
- NewController controller = context.createController("api/components")
+ NewController controller = context.createController(CONTROLLER_COMPONENTS)
.setSince("4.2")
.setDescription("Get information about a component (file, directory, project, ...) and its ancestors or descendants. " +
"Update a project or module key.");
SearchViewComponentsAction.class,
UpdateKeyAction.class,
BulkUpdateKeyAction.class,
- SearchProjectsAction.class);
+ SearchProjectsAction.class,
+ SearchProjectsQueryBuilderValidator.class);
}
}
import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter;
import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_LANGUAGE;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_QUALIFIERS;
@Override
public void define(WebService.NewController context) {
- WebService.NewAction action = context.createAction("search")
+ WebService.NewAction action = context.createAction(ACTION_SEARCH)
.setSince("5.2")
.setInternal(true)
.setDescription("Search for components")
import org.sonarqube.ws.WsComponents.SearchProjectsWsResponse;
import org.sonarqube.ws.client.component.SearchProjectsRequest;
+import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery;
+import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.build;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER;
import static org.sonarqube.ws.client.component.SearchProjectsRequest.DEFAULT_PAGE_SIZE;
import static org.sonarqube.ws.client.component.SearchProjectsRequest.MAX_PAGE_SIZE;
public class SearchProjectsAction implements ComponentsWsAction {
private final DbClient dbClient;
private final ProjectMeasuresIndex index;
+ private final SearchProjectsQueryBuilderValidator searchProjectsQueryBuilderValidator;
- public SearchProjectsAction(DbClient dbClient, ProjectMeasuresIndex index) {
+ public SearchProjectsAction(DbClient dbClient, ProjectMeasuresIndex index, SearchProjectsQueryBuilderValidator searchProjectsQueryBuilderValidator) {
this.dbClient = dbClient;
this.index = index;
+ this.searchProjectsQueryBuilderValidator = searchProjectsQueryBuilderValidator;
}
@Override
public void define(WebService.NewController context) {
- context.createAction("search_projects")
+ WebService.NewAction action = context.createAction("search_projects")
.setSince("6.2")
.setDescription("Search for projects")
.addPagingParams(DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE)
.setInternal(true)
.setResponseExample(getClass().getResource("search_projects-example.json"))
.setHandler(this);
+
+ action
+ .createParam(PARAM_FILTER)
+ .setDescription("TODO")
+ .setSince("6.2");
}
@Override
}
private SearchResults searchProjects(DbSession dbSession, SearchProjectsRequest request) {
+ String filter = request.getFilter();
+ if (filter != null) {
+ SearchProjectsCriteriaQuery query = build(filter);
+ searchProjectsQueryBuilderValidator.validate(dbSession, query);
+ }
SearchIdResult<String> searchResult = index.search(new SearchOptions().setPage(request.getPage(), request.getPageSize()));
Ordering<ComponentDto> ordering = Ordering.explicit(searchResult.getIds()).onResultOf(ComponentDto::uuid);
}
private static SearchProjectsRequest toRequest(Request httpRequest) {
- SearchProjectsRequest.Builder request = SearchProjectsRequest.builder();
-
- request.setPage(httpRequest.mandatoryParamAsInt(Param.PAGE));
- request.setPageSize(httpRequest.mandatoryParamAsInt(Param.PAGE_SIZE));
-
+ SearchProjectsRequest.Builder request = SearchProjectsRequest.builder()
+ .setFilter(httpRequest.param(PARAM_FILTER))
+ .setPage(httpRequest.mandatoryParamAsInt(Param.PAGE))
+ .setPageSize(httpRequest.mandatoryParamAsInt(Param.PAGE_SIZE));
return request.build();
}
--- /dev/null
+/*
+ * SonarQube
+ * 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.sonar.server.component.ws;
+
+import com.google.common.base.Splitter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.lang.String.format;
+import static java.util.Arrays.stream;
+import static java.util.Locale.ENGLISH;
+import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery.MetricCriteria;
+import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery.Operator;
+
+public class SearchProjectsQueryBuilder {
+
+ private static final Splitter CRITERIA_SPLITTER = Splitter.on("and");
+ private static final Pattern CRITERIA_PATTERN = Pattern.compile("(\\w+)\\s*([<>][=]?)\\s*(\\w+)");
+
+ private SearchProjectsQueryBuilder() {
+ // Only static methods
+ }
+
+ public static SearchProjectsCriteriaQuery build(String filter) {
+ SearchProjectsCriteriaQuery query = new SearchProjectsCriteriaQuery();
+ CRITERIA_SPLITTER.split(filter.toLowerCase(ENGLISH))
+ .forEach(criteria -> processCriteria(criteria, query));
+ return query;
+ }
+
+ private static void processCriteria(String criteria, SearchProjectsCriteriaQuery query) {
+ Matcher matcher = CRITERIA_PATTERN.matcher(criteria);
+ checkArgument(matcher.find() && matcher.groupCount() == 3, "Invalid criteria '%s'", criteria);
+ String metric = matcher.group(1);
+ Operator operator = Operator.create(matcher.group(2));
+ Double value = Double.parseDouble(matcher.group(3));
+ query.addMetricCriteria(new MetricCriteria(metric, operator, value));
+ }
+
+ public static class SearchProjectsCriteriaQuery {
+ public enum Operator {
+ LT("<="), GT(">"), EQ("=");
+
+ String value;
+
+ Operator(String value) {
+ this.value = value;
+ }
+
+ String getValue() {
+ return value;
+ }
+
+ public static Operator create(String value) {
+ return stream(Operator.values())
+ .filter(operator -> operator.getValue().equals(value))
+ .findFirst()
+ .orElseThrow(() -> new IllegalArgumentException(format("Unknown operator '%s'", value)));
+ }
+ }
+
+ private List<MetricCriteria> metricCriterias = new ArrayList<>();
+
+ SearchProjectsCriteriaQuery addMetricCriteria(MetricCriteria metricCriteria) {
+ metricCriterias.add(metricCriteria);
+ return this;
+ }
+
+ public List<MetricCriteria> getMetricCriterias() {
+ return metricCriterias;
+ }
+
+ public static class MetricCriteria {
+ private String metricKey;
+ private Operator operator;
+ private double value;
+
+ private MetricCriteria(String metricKey, Operator operator, double value) {
+ this.metricKey = metricKey;
+ this.operator = operator;
+ this.value = value;
+ }
+
+ public String getMetricKey() {
+ return metricKey;
+ }
+
+ public Operator getOperator() {
+ return operator;
+ }
+
+ public double getValue() {
+ return value;
+ }
+ }
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * 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.sonar.server.component.ws;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import org.sonar.core.util.stream.Collectors;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.metric.MetricDto;
+import org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery;
+
+import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery.MetricCriteria;
+
+public class SearchProjectsQueryBuilderValidator {
+
+ private final DbClient dbClient;
+
+ public SearchProjectsQueryBuilderValidator(DbClient dbClient) {
+ this.dbClient = dbClient;
+ }
+
+ public void validate(DbSession dbSession, SearchProjectsCriteriaQuery query) {
+ List<String> metricKeys = new ArrayList<>(query.getMetricCriterias().stream().map(MetricCriteria::getMetricKey).collect(Collectors.toSet()));
+ List<MetricDto> metricDtos = dbClient.metricDao().selectByKeys(dbSession, metricKeys);
+ if (metricDtos.size() == metricKeys.size()) {
+ return;
+ }
+ List<String> metricDtoKeys = metricDtos.stream().map(MetricDto::getKey).collect(Collectors.toList());
+ Set<String> unknownKeys = metricKeys.stream().filter(metricKey -> !metricDtoKeys.contains(metricKey)).collect(Collectors.toSet());
+ throw new IllegalArgumentException(String.format("Unknown metric(s) %s", unknownKeys));
+ }
+}
import org.sonarqube.ws.client.component.UpdateWsRequest;
import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_UPDATE_KEY;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ID;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_KEY;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_NEW_KEY;
@Override
public void define(WebService.NewController context) {
- WebService.NewAction action = context.createAction("update_key")
+ WebService.NewAction action = context.createAction(ACTION_UPDATE_KEY)
.setDescription("Update a project or module key and all its sub-components keys.<br>" +
"Either '%s' or '%s' must be provided, not both.<br> " +
"Requires one of the following permissions: " +
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new ComponentsWsModule().configure(container);
- assertThat(container.size()).isEqualTo(11 + 2);
+ assertThat(container.size()).isEqualTo(12 + 2);
}
}
ComponentDbTester componentDb = new ComponentDbTester(db);
DbClient dbClient = db.getDbClient();
- WsActionTester ws = new WsActionTester(new SearchProjectsAction(dbClient, new ProjectMeasuresIndex(es.client())));
+ WsActionTester ws = new WsActionTester(new SearchProjectsAction(dbClient, new ProjectMeasuresIndex(es.client()), new SearchProjectsQueryBuilderValidator(dbClient)));
SearchProjectsRequest.Builder request = SearchProjectsRequest.builder();
--- /dev/null
+/*
+ * SonarQube
+ * 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.sonar.server.component.ws;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery;
+import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.build;
+import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery.MetricCriteria;
+import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery.Operator;
+
+public class SearchProjectsQueryBuilderTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Test
+ public void create_query() throws Exception {
+ SearchProjectsCriteriaQuery query = build("ncloc > 10 and coverage <= 80");
+
+ assertThat(query.getMetricCriterias())
+ .extracting(MetricCriteria::getMetricKey, MetricCriteria::getOperator, MetricCriteria::getValue)
+ .containsOnly(
+ tuple("ncloc", Operator.GT, 10d),
+ tuple("coverage", Operator.LT, 80d));
+ }
+
+ @Test
+ public void convert_upper_case_to_lower_case() throws Exception {
+ assertThat(build("NCLOC > 10 AND coVERage <= 80").getMetricCriterias())
+ .extracting(MetricCriteria::getMetricKey, MetricCriteria::getOperator, MetricCriteria::getValue)
+ .containsOnly(
+ tuple("ncloc", Operator.GT, 10d),
+ tuple("coverage", Operator.LT, 80d));
+ }
+
+ @Test
+ public void ignore_white_spaces() throws Exception {
+ assertThat(build(" ncloc > 10 ").getMetricCriterias())
+ .extracting(MetricCriteria::getMetricKey, MetricCriteria::getOperator, MetricCriteria::getValue)
+ .containsOnly(tuple("ncloc", Operator.GT, 10d));
+ }
+
+ @Test
+ public void fail_on_unknown_operator() throws Exception {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Unknown operator '>='");
+ build("ncloc >= 10");
+ }
+
+ @Test
+ public void fail_on_invalid_criteria() throws Exception {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Invalid criteria 'ncloc ? 10'");
+ build("ncloc ? 10");
+ }
+
+ @Test
+ public void fail_when_no_operator() throws Exception {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Invalid criteria 'ncloc 10'");
+ build("ncloc 10");
+ }
+
+ @Test
+ public void fail_when_no_key() throws Exception {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Invalid criteria '>= 10'");
+ build(">= 10");
+ }
+
+ @Test
+ public void fail_when_no_value() throws Exception {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Invalid criteria 'ncloc >='");
+ build("ncloc >=");
+ }
+
+ @Test
+ public void fail_when_no_criteria_provided() throws Exception {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Invalid criteria ''");
+ build("");
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * 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.sonar.server.component.ws;
+
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.metric.MetricTesting;
+
+@Ignore
+public class SearchProjectsQueryBuilderValidatorTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public DbTester db = DbTester.create(System2.INSTANCE);
+
+ DbClient dbClient = db.getDbClient();
+ DbSession dbSession = db.getSession();
+
+ SearchProjectsQueryBuilderValidator validator = new SearchProjectsQueryBuilderValidator(dbClient);
+
+ @Test
+ public void does_not_fail_when_metric_criteria_contains_an_existing_metric() throws Exception {
+ insertMetric("ncloc");
+
+ validator.validate(dbSession, SearchProjectsQueryBuilder.build("ncloc > 10"));
+ }
+
+ @Test
+ public void fail_when_metric_does_not_exists() throws Exception {
+ insertMetric("ncloc");
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Unknown metric(s) [unknown]");
+ validator.validate(dbSession, SearchProjectsQueryBuilder.build("unknown > 10"));
+ }
+
+ @Test
+ public void return_all_unknown_metrics() throws Exception {
+ insertMetric("ncloc");
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Unknown metric(s) [coverage, debt]");
+ validator.validate(dbSession, SearchProjectsQueryBuilder.build("debt > 10 AND ncloc <= 20 AND coverage > 30"));
+ }
+
+ private void insertMetric(String metricKey) {
+ dbClient.metricDao().insert(dbSession, MetricTesting.newMetricDto().setKey(metricKey));
+ }
+}
import com.google.common.base.Joiner;
import org.sonarqube.ws.WsComponents.BulkUpdateKeyWsResponse;
+import org.sonarqube.ws.WsComponents.SearchProjectsWsResponse;
import org.sonarqube.ws.WsComponents.SearchWsResponse;
import org.sonarqube.ws.WsComponents.ShowWsResponse;
import org.sonarqube.ws.WsComponents.TreeWsResponse;
import org.sonarqube.ws.client.PostRequest;
import org.sonarqube.ws.client.WsConnector;
+import static org.sonar.api.server.ws.WebService.Param;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_BULK_UPDATE_KEY;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH_PROJECTS;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SHOW;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_TREE;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_UPDATE_KEY;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.CONTROLLER_COMPONENTS;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_BASE_COMPONENT_ID;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_BASE_COMPONENT_KEY;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FROM;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ID;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_KEY;
public class ComponentsService extends BaseService {
public ComponentsService(WsConnector wsConnector) {
- super(wsConnector, "api/components");
+ super(wsConnector, CONTROLLER_COMPONENTS);
}
public SearchWsResponse search(SearchWsRequest request) {
- GetRequest get = new GetRequest(path("search"))
- .setParam("qualifiers", Joiner.on(",").join(request.getQualifiers()))
- .setParam("p", request.getPage())
- .setParam("ps", request.getPageSize())
- .setParam("q", request.getQuery());
+ GetRequest get = new GetRequest(path(ACTION_SEARCH))
+ .setParam(PARAM_QUALIFIERS, Joiner.on(",").join(request.getQualifiers()))
+ .setParam(Param.PAGE, request.getPage())
+ .setParam(Param.PAGE_SIZE, request.getPageSize())
+ .setParam(Param.TEXT_QUERY, request.getQuery());
return call(get, SearchWsResponse.parser());
}
.setParam(PARAM_BASE_COMPONENT_KEY, request.getBaseComponentKey())
.setParam(PARAM_QUALIFIERS, inlineMultipleParamValue(request.getQualifiers()))
.setParam(PARAM_STRATEGY, request.getStrategy())
- .setParam("p", request.getPage())
- .setParam("ps", request.getPageSize())
- .setParam("q", request.getQuery())
- .setParam("s", request.getSort());
+ .setParam(Param.PAGE, request.getPage())
+ .setParam(Param.PAGE_SIZE, request.getPageSize())
+ .setParam(Param.TEXT_QUERY, request.getQuery())
+ .setParam(Param.SORT, request.getSort());
return call(get, TreeWsResponse.parser());
}
}
public void updateKey(UpdateWsRequest request) {
- PostRequest post = new PostRequest(path("update_key"))
+ PostRequest post = new PostRequest(path(ACTION_UPDATE_KEY))
.setParam(PARAM_ID, request.getId())
.setParam(PARAM_KEY, request.getKey())
.setParam(PARAM_NEW_KEY, request.getNewKey());
}
public BulkUpdateKeyWsResponse bulkUpdateKey(BulkUpdateWsRequest request) {
- PostRequest post = new PostRequest(path("bulk_update_key"))
+ PostRequest post = new PostRequest(path(ACTION_BULK_UPDATE_KEY))
.setParam(PARAM_ID, request.getId())
.setParam(PARAM_KEY, request.getKey())
.setParam(PARAM_FROM, request.getFrom())
return call(post, BulkUpdateKeyWsResponse.parser());
}
+
+ public SearchProjectsWsResponse searchProjects(SearchProjectsRequest request) {
+ GetRequest get = new GetRequest(path(ACTION_SEARCH_PROJECTS))
+ .setParam(PARAM_FILTER, request.getFilter())
+ .setParam(Param.PAGE, request.getPage())
+ .setParam(Param.PAGE_SIZE, request.getPageSize());
+ return call(get, SearchProjectsWsResponse.parser());
+ }
}
package org.sonarqube.ws.client.component;
public class ComponentsWsParameters {
+
+ public static final String CONTROLLER_COMPONENTS = "api/components";
+
// actions
+ public static final String ACTION_SEARCH = "search";
+ public static final String ACTION_UPDATE_KEY = "update_key";
public static final String ACTION_TREE = "tree";
-
public static final String ACTION_SHOW = "show";
+ public static final String ACTION_BULK_UPDATE_KEY = "bulk_update_key";
+ public static final String ACTION_SEARCH_PROJECTS = "search_projects";
+
// parameters
public static final String PARAM_QUALIFIERS = "qualifiers";
-
public static final String PARAM_LANGUAGE = "language";
public static final String PARAM_BASE_COMPONENT_ID = "baseComponentId";
public static final String PARAM_BASE_COMPONENT_KEY = "baseComponentKey";
public static final String PARAM_FROM = "from";
public static final String PARAM_TO = "to";
public static final String PARAM_DRY_RUN = "dryRun";
+ public static final String PARAM_FILTER = "filter";
private ComponentsWsParameters() {
// static utility class
private final int page;
private final int pageSize;
+ private final String filter;
private SearchProjectsRequest(Builder builder) {
this.page = builder.page;
this.pageSize = builder.pageSize;
+ this.filter = builder.filter;
+ }
+
+ public String getFilter() {
+ return filter;
}
public int getPageSize() {
public static class Builder {
private Integer page;
private Integer pageSize;
+ private String filter;
private Builder() {
// enforce static factory method
}
+ public Builder setFilter(String filter) {
+ this.filter = filter;
+ return this;
+ }
+
public Builder setPage(int page) {
this.page = page;
return this;
--- /dev/null
+/*
+ * SonarQube
+ * 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.component;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.server.ws.WebService.Param;
+import org.sonarqube.ws.client.ServiceTester;
+import org.sonarqube.ws.client.WsConnector;
+
+import static org.mockito.Mockito.mock;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER;
+
+public class ComponentsServiceTest {
+
+ @Rule
+ public ServiceTester<ComponentsService> serviceTester = new ServiceTester<>(new ComponentsService(mock(WsConnector.class)));
+
+ private ComponentsService underTest = serviceTester.getInstanceUnderTest();
+
+ @Test
+ public void search_projects() {
+ underTest.searchProjects(SearchProjectsRequest.builder()
+ .setFilter("ncloc > 10")
+ .setPage(3)
+ .setPageSize(10)
+ .build());
+
+ serviceTester.assertThat(serviceTester.getGetRequest())
+ .hasPath("search_projects")
+ .hasParam(PARAM_FILTER, "ncloc > 10")
+ .hasParam(Param.PAGE, 3)
+ .hasParam(Param.PAGE_SIZE, 10)
+ .andNoOtherParam();
+ }
+
+}
SearchProjectsRequest.Builder underTest = SearchProjectsRequest.builder();
+ @Test
+ public void filter_parameter() throws Exception {
+ SearchProjectsRequest result = underTest
+ .setFilter("ncloc > 10")
+ .build();
+
+ assertThat(result.getFilter()).isEqualTo("ncloc > 10");
+ }
+
@Test
public void default_page_values() {
SearchProjectsRequest result = underTest.build();