]> source.dussan.org Git - sonarqube.git/commitdiff
Reduce the dependency between sonar-server and sonar-ws
authorDaniel Schwarz <daniel.schwarz@sonarsource.com>
Sat, 25 Nov 2017 07:26:13 +0000 (08:26 +0100)
committerDaniel Schwarz <bartfastiel@users.noreply.github.com>
Wed, 29 Nov 2017 19:24:11 +0000 (20:24 +0100)
By copying the sonar-ws ...Request classes into the ...Action classes (as static inner classes). This will make the refactoring of sonar-ws towards generated Request classes a lot easier.

111 files changed:
server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java
server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityStatusAction.java
server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java
server/sonar-server/src/main/java/org/sonar/server/component/ws/ShowAction.java
server/sonar-server/src/main/java/org/sonar/server/component/ws/TreeAction.java
server/sonar-server/src/main/java/org/sonar/server/favorite/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryFactory.java
server/sonar-server/src/main/java/org/sonar/server/issue/SearchRequest.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/issue/ws/AddCommentAction.java
server/sonar-server/src/main/java/org/sonar/server/issue/ws/ComponentTagsAction.java
server/sonar-server/src/main/java/org/sonar/server/issue/ws/EditCommentAction.java
server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAdditionalField.java
server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentAction.java
server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java
server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeRequest.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeSort.java
server/sonar-server/src/main/java/org/sonar/server/measure/ws/HasMeasure.java
server/sonar-server/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java
server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java
server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchHistoryResult.java
server/sonar-server/src/main/java/org/sonar/server/notification/ws/AddAction.java
server/sonar-server/src/main/java/org/sonar/server/notification/ws/RemoveAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsDataLoader.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddUserToTemplateAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/ApplyTemplateAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/BulkApplyTemplateAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/CreateTemplateAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DeleteTemplateAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveProjectCreatorFromTemplateAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesDataLoader.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SetDefaultTemplateAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/UpdateTemplateAction.java
server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkDeleteAction.java
server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkUpdateKeyAction.java
server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java
server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWsModule.java
server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchMyProjectsAction.java
server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchMyProjectsDataLoader.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchRequest.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java
server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/CreateEventAction.java
server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/DeleteAction.java
server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/DeleteEventAction.java
server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchData.java
server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchRequest.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java
server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/CreateAction.java
server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/DeleteAction.java
server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchGroupsAction.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchUsersAction.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchUsersRequest.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/setting/ws/ListDefinitionsAction.java
server/sonar-server/src/main/java/org/sonar/server/setting/ws/ResetAction.java
server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java
server/sonar-server/src/main/java/org/sonar/server/setting/ws/ValuesAction.java
server/sonar-server/src/main/java/org/sonar/server/user/ws/CreateAction.java
server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java
server/sonar-server/src/main/java/org/sonar/server/user/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/user/ws/UpdateAction.java
server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/GenerateAction.java
server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/RevokeAction.java
server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/SearchAction.java
server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java
server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryFactoryTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/ws/BulkChangeActionTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/ws/ComponentTagsActionTest.java
server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java
server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeSortTest.java
server/sonar-server/src/test/java/org/sonar/server/measure/ws/MeasuresWsModuleTest.java
server/sonar-server/src/test/java/org/sonar/server/measure/ws/MeasuresWsTest.java
server/sonar-server/src/test/java/org/sonar/server/measure/ws/SearchHistoryActionTest.java
server/sonar-server/src/test/java/org/sonar/server/notification/ws/AddActionTest.java
server/sonar-server/src/test/java/org/sonar/server/notification/ws/RemoveActionTest.java
server/sonar-server/src/test/java/org/sonar/server/organization/ws/SearchMembersActionTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/SearchProjectPermissionsActionTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SearchTemplatesActionTest.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/ProjectsWsModuleTest.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/SearchActionTest.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/SearchMyProjectsActionTest.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/SearchMyProjectsDataLoaderTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/projectanalysis/ws/CreateEventActionTest.java
server/sonar-server/src/test/java/org/sonar/server/projectanalysis/ws/SearchActionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/CreateActionTest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/measure/SearchRequest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/settings/SettingsService.java
sonar-ws/src/main/java/org/sonarqube/ws/client/users/ChangePasswordRequest.java [deleted file]
sonar-ws/src/main/java/org/sonarqube/ws/client/users/CreateRequest.java [deleted file]
sonar-ws/src/main/java/org/sonarqube/ws/client/users/DeactivateRequest.java [deleted file]
sonar-ws/src/main/java/org/sonarqube/ws/client/users/GroupsRequest.java [deleted file]
sonar-ws/src/main/java/org/sonarqube/ws/client/users/SearchRequest.java [deleted file]
sonar-ws/src/main/java/org/sonarqube/ws/client/users/UpdateRequest.java [deleted file]
sonar-ws/src/main/java/org/sonarqube/ws/client/users/UsersService.java [deleted file]
sonar-ws/src/main/java/org/sonarqube/ws/client/users/package-info.java [deleted file]

index a98f78d1d914bc6df1df1a33cff9ff6364bdbffc..bd0fcf9de817188a9f570567df86d042fd543f79 100644 (file)
@@ -31,7 +31,6 @@ import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.server.ws.Change;
-import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.server.ws.WebService.Param;
@@ -49,7 +48,6 @@ import org.sonar.db.component.ComponentQuery;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Ce;
 import org.sonarqube.ws.Ce.ActivityResponse;
-import org.sonarqube.ws.client.ce.ActivityRequest;
 
 import static java.lang.Boolean.parseBoolean;
 import static java.lang.Integer.parseInt;
@@ -157,12 +155,12 @@ public class ActivityAction implements CeWsAction {
   }
 
   @Override
-  public void handle(Request wsRequest, Response wsResponse) throws Exception {
+  public void handle(org.sonar.api.server.ws.Request wsRequest, Response wsResponse) throws Exception {
     ActivityResponse activityResponse = doHandle(toSearchWsRequest(wsRequest));
     writeProtobuf(activityResponse, wsRequest, wsResponse);
   }
 
-  private ActivityResponse doHandle(ActivityRequest request) {
+  private ActivityResponse doHandle(Request request) {
 
     try (DbSession dbSession = dbClient.openSession(false)) {
       ComponentDto component = loadComponent(dbSession, request);
@@ -187,7 +185,7 @@ public class ActivityAction implements CeWsAction {
   }
 
   @CheckForNull
-  private ComponentDto loadComponent(DbSession dbSession, ActivityRequest request) {
+  private ComponentDto loadComponent(DbSession dbSession, Request request) {
     String componentId = request.getComponentId();
     if (componentId == null) {
       return null;
@@ -206,7 +204,7 @@ public class ActivityAction implements CeWsAction {
     }
   }
 
-  private Optional<Ce.Task> searchTaskByUuid(DbSession dbSession, ActivityRequest request) {
+  private Optional<Ce.Task> searchTaskByUuid(DbSession dbSession, Request request) {
     String textQuery = request.getQ();
     if (textQuery == null) {
       return Optional.absent();
@@ -221,7 +219,7 @@ public class ActivityAction implements CeWsAction {
     return activity.map(ceActivityDto -> Optional.of(formatter.formatActivity(dbSession, ceActivityDto, null))).orElseGet(Optional::absent);
   }
 
-  private CeTaskQuery buildQuery(DbSession dbSession, ActivityRequest request, @Nullable ComponentDto component) {
+  private CeTaskQuery buildQuery(DbSession dbSession, Request request, @Nullable ComponentDto component) {
     CeTaskQuery query = new CeTaskQuery();
     query.setType(request.getType());
     query.setOnlyCurrents(parseBoolean(request.getOnlyCurrents()));
@@ -252,12 +250,12 @@ public class ActivityAction implements CeWsAction {
     return dbClient.componentDao().selectByQuery(dbSession, componentDtoQuery, 0, CeTaskQuery.MAX_COMPONENT_UUIDS);
   }
 
-  private List<Ce.Task> loadQueuedTasks(DbSession dbSession, ActivityRequest request, CeTaskQuery query) {
+  private List<Ce.Task> loadQueuedTasks(DbSession dbSession, Request request, CeTaskQuery query) {
     List<CeQueueDto> dtos = dbClient.ceQueueDao().selectByQueryInDescOrder(dbSession, query, parseInt(request.getPs()));
     return formatter.formatQueue(dbSession, dtos);
   }
 
-  private List<Ce.Task> loadPastTasks(DbSession dbSession, ActivityRequest request, CeTaskQuery query) {
+  private List<Ce.Task> loadPastTasks(DbSession dbSession, Request request, CeTaskQuery query) {
     List<CeActivityDto> dtos = dbClient.ceActivityDao().selectByQuery(dbSession, query, forPage(1).andSize(parseInt(request.getPs())));
     return formatter.formatActivity(dbSession, dtos);
   }
@@ -282,8 +280,8 @@ public class ActivityAction implements CeWsAction {
     return wsResponseBuilder.build();
   }
 
-  private static ActivityRequest toSearchWsRequest(Request request) {
-    ActivityRequest activityWsRequest = new ActivityRequest()
+  private static Request toSearchWsRequest(org.sonar.api.server.ws.Request request) {
+    Request activityWsRequest = new Request()
       .setComponentId(request.param(PARAM_COMPONENT_ID))
       .setQ(defaultString(request.param(Param.TEXT_QUERY), request.param(PARAM_COMPONENT_QUERY)))
       .setStatus(request.paramAsStrings(PARAM_STATUS))
@@ -297,4 +295,130 @@ public class ActivityAction implements CeWsAction {
       PARAM_COMPONENT_ID, PARAM_COMPONENT_QUERY);
     return activityWsRequest;
   }
+
+  private static class Request {
+
+    private String componentId;
+    private String maxExecutedAt;
+    private String minSubmittedAt;
+    private String onlyCurrents;
+    private String ps;
+    private String q;
+    private List<String> status;
+    private String type;
+
+    /**
+     * Example value: "AU-TpxcA-iU5OvuD2FL0"
+     */
+    private Request setComponentId(String componentId) {
+      this.componentId = componentId;
+      return this;
+    }
+
+    private String getComponentId() {
+      return componentId;
+    }
+
+    /**
+     * Example value: "2017-10-19T13:00:00+0200"
+     */
+    private Request setMaxExecutedAt(String maxExecutedAt) {
+      this.maxExecutedAt = maxExecutedAt;
+      return this;
+    }
+
+    private String getMaxExecutedAt() {
+      return maxExecutedAt;
+    }
+
+    /**
+     * Example value: "2017-10-19T13:00:00+0200"
+     */
+    private Request setMinSubmittedAt(String minSubmittedAt) {
+      this.minSubmittedAt = minSubmittedAt;
+      return this;
+    }
+
+    private String getMinSubmittedAt() {
+      return minSubmittedAt;
+    }
+
+    /**
+     * Possible values:
+     * <ul>
+     *   <li>"true"</li>
+     *   <li>"false"</li>
+     *   <li>"yes"</li>
+     *   <li>"no"</li>
+     * </ul>
+     */
+    private Request setOnlyCurrents(String onlyCurrents) {
+      this.onlyCurrents = onlyCurrents;
+      return this;
+    }
+
+    private String getOnlyCurrents() {
+      return onlyCurrents;
+    }
+
+    /**
+     * Example value: "20"
+     */
+    private Request setPs(String ps) {
+      this.ps = ps;
+      return this;
+    }
+
+    private String getPs() {
+      return ps;
+    }
+
+    /**
+     * Example value: "Apache"
+     */
+    private Request setQ(String q) {
+      this.q = q;
+      return this;
+    }
+
+    private String getQ() {
+      return q;
+    }
+
+    /**
+     * Example value: "IN_PROGRESS,SUCCESS"
+     * Possible values:
+     * <ul>
+     *   <li>"SUCCESS"</li>
+     *   <li>"FAILED"</li>
+     *   <li>"CANCELED"</li>
+     *   <li>"PENDING"</li>
+     *   <li>"IN_PROGRESS"</li>
+     * </ul>
+     */
+    private Request setStatus(List<String> status) {
+      this.status = status;
+      return this;
+    }
+
+    private List<String> getStatus() {
+      return status;
+    }
+
+    /**
+     * Example value: "REPORT"
+     * Possible values:
+     * <ul>
+     *   <li>"REPORT"</li>
+     * </ul>
+     */
+    private Request setType(String type) {
+      this.type = type;
+      return this;
+    }
+
+    private String getType() {
+      return type;
+    }
+  }
 }
index d626c356732a8cd2447216b9f3ea14024678415f..84a7a34cda2a4e26fa686e3a7c98916c0a02e0f0 100644 (file)
@@ -21,7 +21,6 @@ package org.sonar.server.ce.ws;
 
 import com.google.common.base.Optional;
 import org.sonar.api.server.ws.Change;
-import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.web.UserRole;
@@ -35,7 +34,6 @@ import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.user.UserSession;
 import org.sonar.server.ws.KeyExamples;
 import org.sonarqube.ws.Ce.ActivityStatusWsResponse;
-import org.sonarqube.ws.client.ce.ActivityStatusRequest;
 
 import static org.sonar.server.component.ComponentFinder.ParamNames.COMPONENT_ID_AND_KEY;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
@@ -75,12 +73,12 @@ public class ActivityStatusAction implements CeWsAction {
   }
 
   @Override
-  public void handle(Request request, Response response) throws Exception {
+  public void handle(org.sonar.api.server.ws.Request request, Response response) throws Exception {
     ActivityStatusWsResponse activityStatusResponse = doHandle(toWsRequest(request));
     writeProtobuf(activityStatusResponse, request, response);
   }
 
-  private ActivityStatusWsResponse doHandle(ActivityStatusRequest request) {
+  private ActivityStatusWsResponse doHandle(Request request) {
     try (DbSession dbSession = dbClient.openSession(false)) {
       Optional<ComponentDto> component = searchComponent(dbSession, request);
       String componentUuid = component.isPresent() ? component.get().uuid() : null;
@@ -97,7 +95,7 @@ public class ActivityStatusAction implements CeWsAction {
     }
   }
 
-  private Optional<ComponentDto> searchComponent(DbSession dbSession, ActivityStatusRequest request) {
+  private Optional<ComponentDto> searchComponent(DbSession dbSession, Request request) {
     ComponentDto component = null;
     if (hasComponentInRequest(request)) {
       component = componentFinder.getByUuidOrKey(dbSession, request.getComponentId(), request.getComponentKey(), COMPONENT_ID_AND_KEY);
@@ -113,13 +111,37 @@ public class ActivityStatusAction implements CeWsAction {
     }
   }
 
-  private static boolean hasComponentInRequest(ActivityStatusRequest request) {
+  private static boolean hasComponentInRequest(Request request) {
     return request.getComponentId() != null || request.getComponentKey() != null;
   }
 
-  private static ActivityStatusRequest toWsRequest(Request request) {
-    return new ActivityStatusRequest()
+  private static Request toWsRequest(org.sonar.api.server.ws.Request request) {
+    return new Request()
       .setComponentId(request.param(PARAM_COMPONENT_ID))
       .setComponentKey(request.param(DEPRECATED_PARAM_COMPONENT_KEY));
   }
+
+  private static class Request {
+
+    private String componentId;
+    private String componentKey;
+
+    public Request setComponentId(String componentId) {
+      this.componentId = componentId;
+      return this;
+    }
+
+    public String getComponentId() {
+      return componentId;
+    }
+
+    public Request setComponentKey(String componentKey) {
+      this.componentKey = componentKey;
+      return this;
+    }
+
+    public String getComponentKey() {
+      return componentKey;
+    }
+  }
 }
index 2307faf3e85b8854cda144695166c8d1a7ddc531..c6f95f7d8ab51bd6593c38f376361e5590e288ab 100644 (file)
@@ -26,7 +26,6 @@ import java.util.Set;
 import org.sonar.api.i18n.I18n;
 import org.sonar.api.resources.Languages;
 import org.sonar.api.resources.ResourceTypes;
-import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.server.ws.WebService.Param;
@@ -43,9 +42,12 @@ import org.sonar.server.organization.DefaultOrganizationProvider;
 import org.sonar.server.ws.WsUtils;
 import org.sonarqube.ws.Components;
 import org.sonarqube.ws.Components.SearchWsResponse;
-import org.sonarqube.ws.client.component.SearchRequest;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
 import static java.util.stream.Collectors.toMap;
 import static org.sonar.core.util.Protobuf.setNullable;
 import static org.sonar.core.util.stream.MoreCollectors.toHashSet;
@@ -111,12 +113,12 @@ public class SearchAction implements ComponentsWsAction {
   }
 
   @Override
-  public void handle(Request wsRequest, Response wsResponse) throws Exception {
+  public void handle(org.sonar.api.server.ws.Request wsRequest, Response wsResponse) throws Exception {
     SearchWsResponse searchWsResponse = doHandle(toSearchWsRequest(wsRequest));
     writeProtobuf(searchWsResponse, wsRequest, wsResponse);
   }
 
-  private static SearchRequest toSearchWsRequest(Request request) {
+  private static SearchRequest toSearchWsRequest(org.sonar.api.server.ws.Request request) {
     return new SearchRequest()
       .setOrganization(request.param(PARAM_ORGANIZATION))
       .setQualifiers(request.mandatoryParamAsStrings(PARAM_QUALIFIERS))
@@ -197,4 +199,73 @@ public class SearchAction implements ComponentsWsAction {
     return builder.build();
   }
 
+  static class SearchRequest {
+    private String organization;
+    private List<String> qualifiers;
+    private Integer page;
+    private Integer pageSize;
+    private String query;
+    private String language;
+
+    @CheckForNull
+    public String getOrganization() {
+      return organization;
+    }
+
+    public SearchRequest setOrganization(@Nullable String organization) {
+      this.organization = organization;
+      return this;
+    }
+
+    public List<String> getQualifiers() {
+      return qualifiers;
+    }
+
+    public SearchRequest setQualifiers(List<String> qualifiers) {
+      this.qualifiers = requireNonNull(qualifiers);
+      return this;
+    }
+
+    @CheckForNull
+    public Integer getPage() {
+      return page;
+    }
+
+    public SearchRequest setPage(int page) {
+      this.page = page;
+      return this;
+    }
+
+    @CheckForNull
+    public Integer getPageSize() {
+      return pageSize;
+    }
+
+    public SearchRequest setPageSize(int pageSize) {
+      this.pageSize = pageSize;
+      return this;
+    }
+
+    @CheckForNull
+    public String getQuery() {
+      return query;
+    }
+
+    public SearchRequest setQuery(@Nullable String query) {
+      this.query = query;
+      return this;
+    }
+
+    @CheckForNull
+    public String getLanguage() {
+      return language;
+    }
+
+    public SearchRequest setLanguage(@Nullable String language) {
+      this.language = language;
+      return this;
+    }
+  }
+
+
 }
index f114bd780c5147d317f4d0a89d0ef87e25357696..1a6a662e18bd27000181122ddf8153f9f27a8165 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.server.component.ws;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Ordering;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -32,6 +33,7 @@ import java.util.function.Function;
 import java.util.stream.Collector;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
+import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.server.ws.Change;
@@ -58,12 +60,13 @@ import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Common;
 import org.sonarqube.ws.Components.Component;
 import org.sonarqube.ws.Components.SearchProjectsWsResponse;
-import org.sonarqube.ws.client.component.SearchProjectsRequest;
 
 import static com.google.common.base.MoreObjects.firstNonNull;
+import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.collect.Sets.newHashSet;
 import static java.lang.String.format;
 import static java.util.Collections.emptyMap;
+import static java.util.Objects.requireNonNull;
 import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
 import static org.sonar.api.server.ws.WebService.Param.FIELDS;
 import static org.sonar.api.utils.DateUtils.formatDateTime;
@@ -82,13 +85,13 @@ import static org.sonar.server.ws.WsUtils.writeProtobuf;
 import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH_PROJECTS;
 import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER;
 import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
-import static org.sonarqube.ws.client.component.SearchProjectsRequest.DEFAULT_PAGE_SIZE;
-import static org.sonarqube.ws.client.component.SearchProjectsRequest.MAX_PAGE_SIZE;
 import static org.sonarqube.ws.client.project.ProjectsWsParameters.FILTER_LANGUAGES;
 import static org.sonarqube.ws.client.project.ProjectsWsParameters.FILTER_TAGS;
 
 public class SearchProjectsAction implements ComponentsWsAction {
 
+  public static final int MAX_PAGE_SIZE = 500;
+  public static final int DEFAULT_PAGE_SIZE = 100;
   private static final String ANALYSIS_DATE = "analysisDate";
   private static final String LEAK_PERIOD_DATE = "leakPeriodDate";
   private static final Set<String> POSSIBLE_FIELDS = newHashSet(ANALYSIS_DATE, LEAK_PERIOD_DATE);
@@ -289,7 +292,7 @@ public class SearchProjectsAction implements ComponentsWsAction {
   }
 
   private static SearchProjectsRequest toRequest(Request httpRequest) {
-    SearchProjectsRequest.Builder request = SearchProjectsRequest.builder()
+    RequestBuilder request = new RequestBuilder()
       .setOrganization(httpRequest.param(PARAM_ORGANIZATION))
       .setFilter(httpRequest.param(PARAM_FILTER))
       .setSort(httpRequest.mandatoryParam(Param.SORT))
@@ -467,4 +470,133 @@ public class SearchProjectsAction implements ComponentsWsAction {
       this.query = query;
     }
   }
+
+  static class SearchProjectsRequest {
+
+    private final int page;
+    private final int pageSize;
+    private final String organization;
+    private final String filter;
+    private final List<String> facets;
+    private final String sort;
+    private final Boolean asc;
+    private final List<String> additionalFields;
+
+    private SearchProjectsRequest(RequestBuilder builder) {
+      this.page = builder.page;
+      this.pageSize = builder.pageSize;
+      this.organization = builder.organization;
+      this.filter = builder.filter;
+      this.facets = builder.facets;
+      this.sort = builder.sort;
+      this.asc = builder.asc;
+      this.additionalFields = builder.additionalFields;
+    }
+
+    @CheckForNull
+    public String getOrganization() {
+      return organization;
+    }
+
+    @CheckForNull
+    public String getFilter() {
+      return filter;
+    }
+
+    public List<String> getFacets() {
+      return facets;
+    }
+
+    @CheckForNull
+    public String getSort() {
+      return sort;
+    }
+
+    public int getPageSize() {
+      return pageSize;
+    }
+
+    public int getPage() {
+      return page;
+    }
+
+    @CheckForNull
+    public Boolean getAsc() {
+      return asc;
+    }
+
+    public List<String> getAdditionalFields() {
+      return additionalFields;
+    }
+
+    public static RequestBuilder builder() {
+      return new RequestBuilder();
+    }
+  }
+
+  static class RequestBuilder {
+    private String organization;
+    private Integer page;
+    private Integer pageSize;
+    private String filter;
+    private List<String> facets = new ArrayList<>();
+    private String sort;
+    private Boolean asc;
+    private List<String> additionalFields = new ArrayList<>();
+
+    private RequestBuilder() {
+      // enforce static factory method
+    }
+
+    public RequestBuilder setOrganization(@Nullable String organization) {
+      this.organization = organization;
+      return this;
+    }
+
+    public RequestBuilder setFilter(@Nullable String filter) {
+      this.filter = filter;
+      return this;
+    }
+
+    public RequestBuilder setFacets(List<String> facets) {
+      this.facets = requireNonNull(facets);
+      return this;
+    }
+
+    public RequestBuilder setPage(int page) {
+      this.page = page;
+      return this;
+    }
+
+    public RequestBuilder setPageSize(int pageSize) {
+      this.pageSize = pageSize;
+      return this;
+    }
+
+    public RequestBuilder setSort(@Nullable String sort) {
+      this.sort = sort;
+      return this;
+    }
+
+    public RequestBuilder setAsc(boolean asc) {
+      this.asc = asc;
+      return this;
+    }
+
+    public RequestBuilder setAdditionalFields(List<String> additionalFields) {
+      this.additionalFields = requireNonNull(additionalFields, "additional fields cannot be null");
+      return this;
+    }
+
+    public SearchProjectsRequest build() {
+      if (page == null) {
+        page = 1;
+      }
+      if (pageSize == null) {
+        pageSize = DEFAULT_PAGE_SIZE;
+      }
+      checkArgument(pageSize <= MAX_PAGE_SIZE, "Page size must not be greater than %s", MAX_PAGE_SIZE);
+      return new SearchProjectsRequest(this);
+    }
+  }
 }
index 3799794e0122fc2a7769373341fea0015dc7457e..f7bd7a58a85c08d84514799bb2e23a1bf4487a9e 100644 (file)
@@ -23,7 +23,6 @@ import java.util.List;
 import java.util.Optional;
 import java.util.stream.IntStream;
 import org.sonar.api.server.ws.Change;
-import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.web.UserRole;
@@ -35,7 +34,9 @@ import org.sonar.db.organization.OrganizationDto;
 import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Components.ShowWsResponse;
-import org.sonarqube.ws.client.component.ShowRequest;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.lang.String.format;
@@ -99,14 +100,14 @@ public class ShowAction implements ComponentsWsAction {
   }
 
   @Override
-  public void handle(Request request, Response response) throws Exception {
-    ShowRequest showRequest = toShowWsRequest(request);
+  public void handle(org.sonar.api.server.ws.Request request, Response response) throws Exception {
+    Request showRequest = toShowWsRequest(request);
     ShowWsResponse showWsResponse = doHandle(showRequest);
 
     writeProtobuf(showWsResponse, request, response);
   }
 
-  private ShowWsResponse doHandle(ShowRequest request) {
+  private ShowWsResponse doHandle(Request request) {
     try (DbSession dbSession = dbClient.openSession(false)) {
       ComponentDto component = loadComponent(dbSession, request);
       Optional<SnapshotDto> lastAnalysis = dbClient.snapshotDao().selectLastAnalysisByComponentUuid(dbSession, component.projectUuid());
@@ -116,7 +117,7 @@ public class ShowAction implements ComponentsWsAction {
     }
   }
 
-  private ComponentDto loadComponent(DbSession dbSession, ShowRequest request) {
+  private ComponentDto loadComponent(DbSession dbSession, Request request) {
     String componentId = request.getId();
     String componentKey = request.getKey();
     String branch = request.getBranch();
@@ -139,10 +140,46 @@ public class ShowAction implements ComponentsWsAction {
     return response.build();
   }
 
-  private static ShowRequest toShowWsRequest(Request request) {
-    return new ShowRequest()
+  private static Request toShowWsRequest(org.sonar.api.server.ws.Request request) {
+    return new Request()
       .setId(request.param(PARAM_COMPONENT_ID))
       .setKey(request.param(PARAM_COMPONENT))
       .setBranch(request.param(PARAM_BRANCH));
   }
+
+  private static class Request {
+    private String id;
+    private String key;
+    private String branch;
+
+    @CheckForNull
+    public String getId() {
+      return id;
+    }
+
+    public Request setId(@Nullable String id) {
+      this.id = id;
+      return this;
+    }
+
+    @CheckForNull
+    public String getKey() {
+      return key;
+    }
+
+    public Request setKey(@Nullable String key) {
+      this.key = key;
+      return this;
+    }
+
+    @CheckForNull
+    public String getBranch() {
+      return branch;
+    }
+
+    public Request setBranch(@Nullable String branch) {
+      this.branch = branch;
+      return this;
+    }
+  }
 }
index e2c31ae4325b58d8b887834ebfebade1eacc8aa1..6a6ac04d04961ee24f433c02af30f8cc85c03c24 100644 (file)
@@ -32,10 +32,10 @@ import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 import org.sonar.api.i18n.I18n;
 import org.sonar.api.resources.ResourceTypes;
 import org.sonar.api.server.ws.Change;
-import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.server.ws.WebService.Param;
@@ -52,7 +52,6 @@ import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Components;
 import org.sonarqube.ws.Components.TreeWsResponse;
-import org.sonarqube.ws.client.component.TreeRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.lang.String.CASE_INSENSITIVE_ORDER;
@@ -144,10 +143,10 @@ public class TreeAction implements ComponentsWsAction {
       .setExampleValue(NAME_SORT + ", " + PATH_SORT);
 
     action.createParam(Param.TEXT_QUERY)
-      .setDescription(format("Limit search to: <ul>" +
+      .setDescription("Limit search to: <ul>" +
         "<li>component names that contain the supplied string</li>" +
         "<li>component keys that are exactly the same as the supplied string</li>" +
-        "</ul>"))
+        "</ul>")
       .setMinimumLength(QUERY_MINIMUM_LENGTH)
       .setExampleValue("FILE_NAM");
 
@@ -165,12 +164,12 @@ public class TreeAction implements ComponentsWsAction {
   }
 
   @Override
-  public void handle(Request request, Response response) throws Exception {
+  public void handle(org.sonar.api.server.ws.Request request, Response response) throws Exception {
     TreeWsResponse treeWsResponse = doHandle(toTreeWsRequest(request));
     writeProtobuf(treeWsResponse, request, response);
   }
 
-  private TreeWsResponse doHandle(TreeRequest treeRequest) {
+  private TreeWsResponse doHandle(Request treeRequest) {
     try (DbSession dbSession = dbClient.openSession(false)) {
       ComponentDto baseComponent = loadComponent(dbSession, treeRequest);
       checkPermissions(baseComponent);
@@ -189,7 +188,7 @@ public class TreeAction implements ComponentsWsAction {
     }
   }
 
-  private ComponentDto loadComponent(DbSession dbSession, TreeRequest request) {
+  private ComponentDto loadComponent(DbSession dbSession, Request request) {
     String componentId = request.getBaseComponentId();
     String componentKey = request.getBaseComponentKey();
     String branch = request.getBranch();
@@ -234,7 +233,7 @@ public class TreeAction implements ComponentsWsAction {
   }
 
   private static Components.Component.Builder toWsComponent(ComponentDto component, OrganizationDto organizationDto,
-                                                            Map<String, ComponentDto> referenceComponentsByUuid) {
+    Map<String, ComponentDto> referenceComponentsByUuid) {
     Components.Component.Builder wsComponent = componentDtoToWsComponent(component, organizationDto, Optional.empty());
 
     ComponentDto referenceComponent = referenceComponentsByUuid.get(component.getCopyResourceUuid());
@@ -246,7 +245,7 @@ public class TreeAction implements ComponentsWsAction {
     return wsComponent;
   }
 
-  private ComponentTreeQuery toComponentTreeQuery(TreeRequest request, ComponentDto baseComponent) {
+  private ComponentTreeQuery toComponentTreeQuery(Request request, ComponentDto baseComponent) {
     List<String> childrenQualifiers = childrenQualifiers(request, baseComponent.qualifier());
 
     ComponentTreeQuery.Builder query = ComponentTreeQuery.builder()
@@ -263,7 +262,7 @@ public class TreeAction implements ComponentsWsAction {
   }
 
   @CheckForNull
-  private List<String> childrenQualifiers(TreeRequest request, String baseQualifier) {
+  private List<String> childrenQualifiers(Request request, String baseQualifier) {
     List<String> requestQualifiers = request.getQualifiers();
     List<String> childrenQualifiers = null;
     if (LEAVES_STRATEGY.equals(request.getStrategy())) {
@@ -283,8 +282,8 @@ public class TreeAction implements ComponentsWsAction {
     return new ArrayList<>(qualifiersIntersection);
   }
 
-  private static TreeRequest toTreeWsRequest(Request request) {
-    return new TreeRequest()
+  private static Request toTreeWsRequest(org.sonar.api.server.ws.Request request) {
+    return new Request()
       .setBaseComponentId(request.param(PARAM_COMPONENT_ID))
       .setBaseComponentKey(request.param(PARAM_COMPONENT))
       .setBranch(request.param(PARAM_BRANCH))
@@ -297,12 +296,12 @@ public class TreeAction implements ComponentsWsAction {
       .setPageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE));
   }
 
-  private static List<ComponentDto> paginateComponents(List<ComponentDto> components, TreeRequest wsRequest) {
+  private static List<ComponentDto> paginateComponents(List<ComponentDto> components, Request wsRequest) {
     return components.stream().skip(offset(wsRequest.getPage(), wsRequest.getPageSize()))
       .limit(wsRequest.getPageSize()).collect(toList());
   }
 
-  public static List<ComponentDto> sortComponents(List<ComponentDto> components, TreeRequest wsRequest) {
+  private static List<ComponentDto> sortComponents(List<ComponentDto> components, Request wsRequest) {
     List<String> sortParameters = wsRequest.getSort();
     if (sortParameters == null || sortParameters.isEmpty()) {
       return components;
@@ -334,4 +333,143 @@ public class TreeAction implements ComponentsWsAction {
     return ordering.nullsLast().onResultOf(function);
   }
 
+  private static class Request {
+    private String baseComponentId;
+    private String baseComponentKey;
+    private String component;
+    private String branch;
+    private String strategy;
+    private List<String> qualifiers;
+    private String query;
+    private List<String> sort;
+    private Boolean asc;
+    private Integer page;
+    private Integer pageSize;
+
+    /**
+     * @deprecated since 6.4, please use {@link #getComponent()} instead
+     */
+    @Deprecated
+    @CheckForNull
+    private String getBaseComponentId() {
+      return baseComponentId;
+    }
+
+    /**
+     * @deprecated since 6.4, please use {@link #setComponent(String)} instead
+     */
+    @Deprecated
+    private Request setBaseComponentId(@Nullable String baseComponentId) {
+      this.baseComponentId = baseComponentId;
+      return this;
+    }
+
+    /**
+     * @deprecated since 6.4, please use {@link #getComponent()} instead
+     */
+    @Deprecated
+    @CheckForNull
+    private String getBaseComponentKey() {
+      return baseComponentKey;
+    }
+
+    /**
+     * @deprecated since 6.4, please use {@link #setComponent(String)} instead
+     */
+    @Deprecated
+    private Request setBaseComponentKey(@Nullable String baseComponentKey) {
+      this.baseComponentKey = baseComponentKey;
+      return this;
+    }
+
+    public Request setComponent(@Nullable String component) {
+      this.component = component;
+      return this;
+    }
+
+    @CheckForNull
+    private String getComponent() {
+      return component;
+    }
+
+    @CheckForNull
+    private String getBranch() {
+      return branch;
+    }
+
+    private Request setBranch(@Nullable String branch) {
+      this.branch = branch;
+      return this;
+    }
+
+    @CheckForNull
+    private String getStrategy() {
+      return strategy;
+    }
+
+    private Request setStrategy(@Nullable String strategy) {
+      this.strategy = strategy;
+      return this;
+    }
+
+    @CheckForNull
+    private List<String> getQualifiers() {
+      return qualifiers;
+    }
+
+    private Request setQualifiers(@Nullable List<String> qualifiers) {
+      this.qualifiers = qualifiers;
+      return this;
+    }
+
+    @CheckForNull
+    private String getQuery() {
+      return query;
+    }
+
+    private Request setQuery(@Nullable String query) {
+      this.query = query;
+      return this;
+    }
+
+    @CheckForNull
+    private List<String> getSort() {
+      return sort;
+    }
+
+    private Request setSort(@Nullable List<String> sort) {
+      this.sort = sort;
+      return this;
+    }
+
+    private Boolean getAsc() {
+      return asc;
+    }
+
+    private Request setAsc(@Nullable Boolean asc) {
+      this.asc = asc;
+      return this;
+    }
+
+    @CheckForNull
+    private Integer getPage() {
+      return page;
+    }
+
+    private Request setPage(@Nullable Integer page) {
+      this.page = page;
+      return this;
+    }
+
+    @CheckForNull
+    private Integer getPageSize() {
+      return pageSize;
+    }
+
+    private Request setPageSize(@Nullable Integer pageSize) {
+      this.pageSize = pageSize;
+      return this;
+    }
+  }
+
 }
index 6b7b6ce40be82b1a4a718c0c768c72b12fd75352..50f20a4e8f0a2932aa62a2fc856eb3d6fd0b50ca 100644 (file)
@@ -38,7 +38,6 @@ import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Common;
 import org.sonarqube.ws.Favorites.Favorite;
 import org.sonarqube.ws.Favorites.SearchResponse;
-import org.sonarqube.ws.client.favorites.SearchRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static org.sonar.core.util.Protobuf.setNullable;
@@ -160,4 +159,27 @@ public class SearchAction implements FavoritesWsAction {
     return builder.build();
   }
 
+  private static class SearchRequest {
+
+    private String p;
+    private String ps;
+
+    public SearchRequest setP(String p) {
+      this.p = p;
+      return this;
+    }
+
+    public String getP() {
+      return p;
+    }
+
+    public SearchRequest setPs(String ps) {
+      this.ps = ps;
+      return this;
+    }
+
+    public String getPs() {
+      return ps;
+    }
+  }
 }
index a4a2f341f48fb96c5476839af8cf75302303c15c..fb225976eb5111e09fd7d5ff5437bb708786c255 100644 (file)
@@ -53,7 +53,6 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.issue.SearchRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.collect.Lists.newArrayList;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/SearchRequest.java b/server/sonar-server/src/main/java/org/sonar/server/issue/SearchRequest.java
new file mode 100644 (file)
index 0000000..fd8f4de
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.issue;
+
+import java.util.List;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+public class SearchRequest {
+  private List<String> actionPlans;
+  private List<String> additionalFields;
+  private Boolean asc;
+  private Boolean assigned;
+  private List<String> assignees;
+  private List<String> authors;
+  private List<String> componentKeys;
+  private List<String> componentRootUuids;
+  private List<String> componentRoots;
+  private List<String> componentUuids;
+  private List<String> components;
+  private String createdAfter;
+  private String createdAt;
+  private String createdBefore;
+  private String createdInLast;
+  private List<String> directories;
+  private String facetMode;
+  private List<String> facets;
+  private List<String> fileUuids;
+  private List<String> issues;
+  private List<String> languages;
+  private List<String> moduleUuids;
+  private Boolean onComponentOnly;
+  private String branch;
+  private String organization;
+  private Integer page;
+  private Integer pageSize;
+  private List<String> projectKeys;
+  private List<String> projectUuids;
+  private List<String> projects;
+  private List<String> resolutions;
+  private Boolean resolved;
+  private List<String> rules;
+  private Boolean sinceLeakPeriod;
+  private String sort;
+  private List<String> severities;
+  private List<String> statuses;
+  private List<String> tags;
+  private List<String> types;
+
+  @CheckForNull
+  public List<String> getActionPlans() {
+    return actionPlans;
+  }
+
+  public SearchRequest setActionPlans(@Nullable List<String> actionPlans) {
+    this.actionPlans = actionPlans;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getAdditionalFields() {
+    return additionalFields;
+  }
+
+  public SearchRequest setAdditionalFields(@Nullable List<String> additionalFields) {
+    this.additionalFields = additionalFields;
+    return this;
+  }
+
+  @CheckForNull
+  public Boolean getAsc() {
+    return asc;
+  }
+
+  public SearchRequest setAsc(boolean asc) {
+    this.asc = asc;
+    return this;
+  }
+
+  @CheckForNull
+  public Boolean getAssigned() {
+    return assigned;
+  }
+
+  public SearchRequest setAssigned(@Nullable Boolean assigned) {
+    this.assigned = assigned;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getAssignees() {
+    return assignees;
+  }
+
+  public SearchRequest setAssignees(@Nullable List<String> assignees) {
+    this.assignees = assignees;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getAuthors() {
+    return authors;
+  }
+
+  public SearchRequest setAuthors(@Nullable List<String> authors) {
+    this.authors = authors;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getComponentKeys() {
+    return componentKeys;
+  }
+
+  public SearchRequest setComponentKeys(@Nullable List<String> componentKeys) {
+    this.componentKeys = componentKeys;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getComponentUuids() {
+    return componentUuids;
+  }
+
+  public SearchRequest setComponentUuids(@Nullable List<String> componentUuids) {
+    this.componentUuids = componentUuids;
+    return this;
+  }
+
+  @CheckForNull
+  public String getCreatedAfter() {
+    return createdAfter;
+  }
+
+  public SearchRequest setCreatedAfter(@Nullable String createdAfter) {
+    this.createdAfter = createdAfter;
+    return this;
+  }
+
+  @CheckForNull
+  public String getCreatedAt() {
+    return createdAt;
+  }
+
+  public SearchRequest setCreatedAt(@Nullable String createdAt) {
+    this.createdAt = createdAt;
+    return this;
+  }
+
+  @CheckForNull
+  public String getCreatedBefore() {
+    return createdBefore;
+  }
+
+  public SearchRequest setCreatedBefore(@Nullable String createdBefore) {
+    this.createdBefore = createdBefore;
+    return this;
+  }
+
+  @CheckForNull
+  public String getCreatedInLast() {
+    return createdInLast;
+  }
+
+  public SearchRequest setCreatedInLast(@Nullable String createdInLast) {
+    this.createdInLast = createdInLast;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getDirectories() {
+    return directories;
+  }
+
+  public SearchRequest setDirectories(@Nullable List<String> directories) {
+    this.directories = directories;
+    return this;
+  }
+
+  @CheckForNull
+  public String getFacetMode() {
+    return facetMode;
+  }
+
+  public SearchRequest setFacetMode(@Nullable String facetMode) {
+    this.facetMode = facetMode;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getFacets() {
+    return facets;
+  }
+
+  public SearchRequest setFacets(@Nullable List<String> facets) {
+    this.facets = facets;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getFileUuids() {
+    return fileUuids;
+  }
+
+  public SearchRequest setFileUuids(@Nullable List<String> fileUuids) {
+    this.fileUuids = fileUuids;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getIssues() {
+    return issues;
+  }
+
+  public SearchRequest setIssues(@Nullable List<String> issues) {
+    this.issues = issues;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getLanguages() {
+    return languages;
+  }
+
+  public SearchRequest setLanguages(@Nullable List<String> languages) {
+    this.languages = languages;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getModuleUuids() {
+    return moduleUuids;
+  }
+
+  public SearchRequest setModuleUuids(@Nullable List<String> moduleUuids) {
+    this.moduleUuids = moduleUuids;
+    return this;
+  }
+
+  @CheckForNull
+  public Boolean getOnComponentOnly() {
+    return onComponentOnly;
+  }
+
+  public SearchRequest setOnComponentOnly(Boolean onComponentOnly) {
+    this.onComponentOnly = onComponentOnly;
+    return this;
+  }
+
+  @CheckForNull
+  public String getOrganization() {
+    return organization;
+  }
+
+  public SearchRequest setOrganization(@Nullable String s) {
+    this.organization = s;
+    return this;
+  }
+
+  @CheckForNull
+  public Integer getPage() {
+    return page;
+  }
+
+  public SearchRequest setPage(int page) {
+    this.page = page;
+    return this;
+  }
+
+  @CheckForNull
+  public Integer getPageSize() {
+    return pageSize;
+  }
+
+  public SearchRequest setPageSize(int pageSize) {
+    this.pageSize = pageSize;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getProjectKeys() {
+    return projectKeys;
+  }
+
+  public SearchRequest setProjectKeys(@Nullable List<String> projectKeys) {
+    this.projectKeys = projectKeys;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getProjectUuids() {
+    return projectUuids;
+  }
+
+  public SearchRequest setProjectUuids(@Nullable List<String> projectUuids) {
+    this.projectUuids = projectUuids;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getResolutions() {
+    return resolutions;
+  }
+
+  public SearchRequest setResolutions(@Nullable List<String> resolutions) {
+    this.resolutions = resolutions;
+    return this;
+  }
+
+  @CheckForNull
+  public Boolean getResolved() {
+    return resolved;
+  }
+
+  public SearchRequest setResolved(@Nullable Boolean resolved) {
+    this.resolved = resolved;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getRules() {
+    return rules;
+  }
+
+  public SearchRequest setRules(@Nullable List<String> rules) {
+    this.rules = rules;
+    return this;
+  }
+
+  @CheckForNull
+  public Boolean getSinceLeakPeriod() {
+    return sinceLeakPeriod;
+  }
+
+  public SearchRequest setSinceLeakPeriod(@Nullable Boolean sinceLeakPeriod) {
+    this.sinceLeakPeriod = sinceLeakPeriod;
+    return this;
+  }
+
+  @CheckForNull
+  public String getSort() {
+    return sort;
+  }
+
+  public SearchRequest setSort(@Nullable String sort) {
+    this.sort = sort;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getSeverities() {
+    return severities;
+  }
+
+  public SearchRequest setSeverities(@Nullable List<String> severities) {
+    this.severities = severities;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getStatuses() {
+    return statuses;
+  }
+
+  public SearchRequest setStatuses(@Nullable List<String> statuses) {
+    this.statuses = statuses;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getTags() {
+    return tags;
+  }
+
+  public SearchRequest setTags(@Nullable List<String> tags) {
+    this.tags = tags;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getTypes() {
+    return types;
+  }
+
+  public SearchRequest setTypes(@Nullable List<String> types) {
+    this.types = types;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getComponentRootUuids() {
+    return componentRootUuids;
+  }
+
+  public SearchRequest setComponentRootUuids(List<String> componentRootUuids) {
+    this.componentRootUuids = componentRootUuids;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getComponentRoots() {
+    return componentRoots;
+  }
+
+  public SearchRequest setComponentRoots(@Nullable List<String> componentRoots) {
+    this.componentRoots = componentRoots;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getComponents() {
+    return components;
+  }
+
+  public SearchRequest setComponents(@Nullable List<String> components) {
+    this.components = components;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getProjects() {
+    return projects;
+  }
+
+  public SearchRequest setProjects(@Nullable List<String> projects) {
+    this.projects = projects;
+    return this;
+  }
+
+  @CheckForNull
+  public String getBranch() {
+    return branch;
+  }
+
+  public SearchRequest setBranch(@Nullable String branch) {
+    this.branch = branch;
+    return this;
+  }
+}
index 9eed23186c167231844d97182e9841851640847a..ad9ede47da1ff601a7214559a9f5eb2c757c9e9c 100644 (file)
@@ -35,11 +35,11 @@ import org.sonar.server.issue.IssueFieldsSetter;
 import org.sonar.server.issue.IssueFinder;
 import org.sonar.server.issue.IssueUpdater;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.issue.AddCommentRequest;
 import org.sonarqube.ws.client.issue.IssuesWsParameters;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Strings.isNullOrEmpty;
+import static java.util.Objects.requireNonNull;
 import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
 import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ISSUE;
 import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TEXT;
@@ -109,4 +109,22 @@ public class AddCommentAction implements IssuesWsAction {
     return wsRequest;
   }
 
+  private static class AddCommentRequest {
+
+    private final String issue;
+    private final String text;
+
+    private AddCommentRequest(String issue, String text) {
+      this.issue = requireNonNull(issue, "Issue key cannot be null");
+      this.text = requireNonNull(text, "Text cannot be null");
+    }
+
+    public String getIssue() {
+      return issue;
+    }
+
+    public String getText() {
+      return text;
+    }
+  }
 }
index 5bb5d38c8f1c4da8e368d68c95a7544c67ae630e..7e1ed580894e3b4e97442d3d720307ac2bffbe75 100644 (file)
@@ -29,7 +29,7 @@ import org.sonar.api.utils.text.JsonWriter;
 import org.sonar.server.issue.IssueQuery;
 import org.sonar.server.issue.IssueQueryFactory;
 import org.sonar.server.issue.index.IssueIndex;
-import org.sonarqube.ws.client.issue.SearchRequest;
+import org.sonar.server.issue.SearchRequest;
 
 import static java.util.Collections.singletonList;
 import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
index e834162237e713c0d81d0868cf40ab4eb2fbde1a..cc7244edb26f6833592deb6adf3c63ca93a17a42 100644 (file)
@@ -37,11 +37,11 @@ import org.sonar.db.issue.IssueDto;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.issue.IssueFinder;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.issue.EditCommentRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Strings.isNullOrEmpty;
 import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
 import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
 import static org.sonarqube.ws.client.issue.IssuesWsParameters.ACTION_EDIT_COMMENT;
 import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMMENT;
@@ -152,4 +152,22 @@ public class EditCommentAction implements IssuesWsAction {
     }
   }
 
+  public static class EditCommentRequest {
+
+    private final String comment;
+    private final String text;
+
+    public EditCommentRequest(String comment, String text) {
+      this.comment = requireNonNull(comment, "Comment key cannot be null");
+      this.text = requireNonNull(text, "Text cannot be null");
+    }
+
+    public String getComment() {
+      return comment;
+    }
+
+    public String getText() {
+      return text;
+    }
+  }
 }
index b8b744d83eb4c2683e9ade2f5ac2c07d7d01e45a..2d2355dc612e7578593ff9598b9cc8a5ad696b96 100644 (file)
@@ -51,7 +51,7 @@ import org.sonar.server.issue.IssueQueryFactory;
 import org.sonar.server.issue.index.IssueIndex;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Issues.SearchWsResponse;
-import org.sonarqube.ws.client.issue.SearchRequest;
+import org.sonar.server.issue.SearchRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.collect.Iterables.concat;
index 0c8ef7e9224c4adc9ba45e05954961a3f973c873..431a5aa914062bf71402ba90446e6893f2bbe11d 100644 (file)
@@ -26,7 +26,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import javax.annotation.CheckForNull;
-import org.sonarqube.ws.client.issue.SearchRequest;
+import org.sonar.server.issue.SearchRequest;
 
 public enum SearchAdditionalField {
 
index fd5d78e90ef87ae373950b926a358dd93cd255cf..59633ac3d74ac187f96144be0b98f0cad41d2e6b 100644 (file)
@@ -53,7 +53,6 @@ import org.sonar.server.measure.ws.MetricDtoWithBestValue.MetricDtoToMetricDtoWi
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Measures;
 import org.sonarqube.ws.Measures.ComponentWsResponse;
-import org.sonarqube.ws.client.measure.ComponentRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.lang.String.format;
@@ -181,7 +180,7 @@ public class ComponentAction implements MeasuresWsAction {
   }
 
   private static ComponentWsResponse buildResponse(ComponentRequest request, ComponentDto component, Optional<ComponentDto> refComponent, List<MeasureDto> measures,
-                                                   List<MetricDto> metrics, List<Measures.Period> periods) {
+    List<MetricDto> metrics, List<Measures.Period> periods) {
     ComponentWsResponse.Builder response = ComponentWsResponse.newBuilder();
     Map<Integer, MetricDto> metricsById = Maps.uniqueIndex(metrics, MetricDto::getId);
     Map<MetricDto, MeasureDto> measuresByMetric = new HashMap<>();
@@ -282,4 +281,91 @@ public class ComponentAction implements MeasuresWsAction {
   private void checkPermissions(ComponentDto baseComponent) {
     userSession.checkComponentPermission(UserRole.USER, baseComponent);
   }
+
+  private static class ComponentRequest {
+    private String componentId;
+    private String component;
+    private String branch;
+    private List<String> metricKeys;
+    private List<String> additionalFields;
+    private String developerId;
+    private String developerKey;
+
+    /**
+     * @deprecated since 6.6, please use {@link #getComponent()} instead
+     */
+    @Deprecated
+    @CheckForNull
+    private String getComponentId() {
+      return componentId;
+    }
+
+    /**
+     * @deprecated since 6.6, please use {@link #setComponent(String)} instead
+     */
+    @Deprecated
+    private ComponentRequest setComponentId(@Nullable String componentId) {
+      this.componentId = componentId;
+      return this;
+    }
+
+    @CheckForNull
+    private String getComponent() {
+      return component;
+    }
+
+    private ComponentRequest setComponent(@Nullable String component) {
+      this.component = component;
+      return this;
+    }
+
+    @CheckForNull
+    private String getBranch() {
+      return branch;
+    }
+
+    private ComponentRequest setBranch(@Nullable String branch) {
+      this.branch = branch;
+      return this;
+    }
+
+    private List<String> getMetricKeys() {
+      return metricKeys;
+    }
+
+    private ComponentRequest setMetricKeys(@Nullable List<String> metricKeys) {
+      this.metricKeys = metricKeys;
+      return this;
+    }
+
+    @CheckForNull
+    private List<String> getAdditionalFields() {
+      return additionalFields;
+    }
+
+    private ComponentRequest setAdditionalFields(@Nullable List<String> additionalFields) {
+      this.additionalFields = additionalFields;
+      return this;
+    }
+
+    @CheckForNull
+    private String getDeveloperId() {
+      return developerId;
+    }
+
+    private ComponentRequest setDeveloperId(@Nullable String developerId) {
+      this.developerId = developerId;
+      return this;
+    }
+
+    @CheckForNull
+    private String getDeveloperKey() {
+      return developerKey;
+    }
+
+    private ComponentRequest setDeveloperKey(@Nullable String developerKey) {
+      this.developerKey = developerKey;
+      return this;
+    }
+  }
 }
index b9f79a6beef9aca54bcd7aa4ae2625784d3e2267..e47c71bb1a6fea1e75524b645f11c481506fd28a 100644 (file)
 package org.sonar.server.measure.ws;
 
 import com.google.common.base.Joiner;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.HashBasedTable;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.collect.Table;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import org.sonar.api.i18n.I18n;
+import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.resources.ResourceTypes;
 import org.sonar.api.server.ws.Change;
 import org.sonar.api.server.ws.Request;
@@ -35,31 +53,49 @@ import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.api.utils.Paging;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.util.stream.MoreCollectors;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTreeQuery;
 import org.sonar.db.component.ComponentTreeQuery.Strategy;
+import org.sonar.db.component.SnapshotDto;
+import org.sonar.db.measure.MeasureDto;
+import org.sonar.db.measure.MeasureTreeQuery;
 import org.sonar.db.metric.MetricDto;
+import org.sonar.db.metric.MetricDtoFunctions;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Measures;
 import org.sonarqube.ws.Measures.ComponentTreeWsResponse;
-import org.sonarqube.ws.client.measure.ComponentTreeRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
 import static java.lang.String.format;
 import static java.util.Collections.emptyList;
+import static java.util.Collections.emptyMap;
+import static java.util.Objects.requireNonNull;
 import static org.sonar.api.measures.Metric.ValueType.DATA;
 import static org.sonar.api.measures.Metric.ValueType.DISTRIB;
+import static org.sonar.api.utils.Paging.offset;
 import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02;
 import static org.sonar.db.component.ComponentTreeQuery.Strategy.CHILDREN;
 import static org.sonar.db.component.ComponentTreeQuery.Strategy.LEAVES;
+import static org.sonar.server.component.ComponentFinder.ParamNames.BASE_COMPONENT_ID_AND_KEY;
+import static org.sonar.server.component.ComponentFinder.ParamNames.DEVELOPER_ID_AND_KEY;
 import static org.sonar.server.measure.ws.ComponentDtoToWsComponent.componentDtoToWsComponent;
 import static org.sonar.server.measure.ws.MeasureDtoToWsMeasure.updateMeasureBuilder;
 import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createAdditionalFieldsParameter;
 import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createDeveloperParameters;
 import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createMetricKeysParameter;
 import static org.sonar.server.measure.ws.MetricDtoToWsMetric.metricDtoToWsMetric;
+import static org.sonar.server.measure.ws.SnapshotDtoToWsPeriods.snapshotToWsPeriods;
 import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
 import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
-import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter;
 import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
+import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter;
 import static org.sonar.server.ws.WsUtils.checkRequest;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.ACTION_COMPONENT_TREE;
@@ -119,14 +155,19 @@ public class ComponentTreeAction implements MeasuresWsAction {
   static final Set<String> FORBIDDEN_METRIC_TYPES = ImmutableSet.of(DISTRIB.name(), DATA.name());
   private static final int MAX_METRIC_KEYS = 15;
   private static final Joiner COMMA_JOINER = Joiner.on(", ");
+  private static final Set<String> QUALIFIERS_ELIGIBLE_FOR_BEST_VALUE = ImmutableSet.of(Qualifiers.FILE, Qualifiers.UNIT_TEST_FILE);
 
-  private final ComponentTreeDataLoader dataLoader;
+  private final DbClient dbClient;
+  private final ComponentFinder componentFinder;
+  private final UserSession userSession;
   private final I18n i18n;
   private final ResourceTypes resourceTypes;
 
-  public ComponentTreeAction(ComponentTreeDataLoader dataLoader, I18n i18n,
+  public ComponentTreeAction(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, I18n i18n,
     ResourceTypes resourceTypes) {
-    this.dataLoader = dataLoader;
+    this.dbClient = dbClient;
+    this.componentFinder = componentFinder;
+    this.userSession = userSession;
     this.i18n = i18n;
     this.resourceTypes = resourceTypes;
   }
@@ -220,7 +261,7 @@ public class ComponentTreeAction implements MeasuresWsAction {
   }
 
   private ComponentTreeWsResponse doHandle(ComponentTreeRequest request) {
-    ComponentTreeData data = dataLoader.load(request);
+    ComponentTreeData data = load(request);
     if (data.getComponents() == null) {
       return emptyResponse(data.getBaseComponent(), request);
     }
@@ -344,4 +385,238 @@ public class ComponentTreeAction implements MeasuresWsAction {
     return wsComponent;
   }
 
+  private ComponentTreeData load(ComponentTreeRequest wsRequest) {
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      ComponentDto baseComponent = loadComponent(dbSession, wsRequest);
+      checkPermissions(baseComponent);
+      Optional<SnapshotDto> baseSnapshot = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(dbSession, baseComponent.projectUuid());
+      if (!baseSnapshot.isPresent()) {
+        return ComponentTreeData.builder()
+                .setBaseComponent(baseComponent)
+                .build();
+      }
+      Long developerId = searchDeveloperId(dbSession, wsRequest);
+
+      ComponentTreeQuery componentTreeQuery = toComponentTreeQuery(wsRequest, baseComponent);
+      List<ComponentDto> components = searchComponents(dbSession, componentTreeQuery);
+      List<MetricDto> metrics = searchMetrics(dbSession, wsRequest);
+      Table<String, MetricDto, ComponentTreeData.Measure> measuresByComponentUuidAndMetric = searchMeasuresByComponentUuidAndMetric(dbSession, baseComponent, componentTreeQuery,
+              components,
+              metrics, developerId);
+
+      components = filterComponents(components, measuresByComponentUuidAndMetric, metrics, wsRequest);
+      components = sortComponents(components, wsRequest, metrics, measuresByComponentUuidAndMetric);
+
+      int componentCount = components.size();
+      components = paginateComponents(components, wsRequest);
+
+      return ComponentTreeData.builder()
+              .setBaseComponent(baseComponent)
+              .setComponentsFromDb(components)
+              .setComponentCount(componentCount)
+              .setMeasuresByComponentUuidAndMetric(measuresByComponentUuidAndMetric)
+              .setMetrics(metrics)
+              .setPeriods(snapshotToWsPeriods(baseSnapshot.get()))
+              .setReferenceComponentsByUuid(searchReferenceComponentsById(dbSession, components))
+              .build();
+    }
+  }
+
+  private ComponentDto loadComponent(DbSession dbSession, ComponentTreeRequest request) {
+    String componentKey = request.getComponent();
+    String componentId = request.getBaseComponentId();
+    String branch = request.getBranch();
+    checkArgument(componentId == null || branch == null, "'%s' and '%s' parameters cannot be used at the same time", DEPRECATED_PARAM_BASE_COMPONENT_ID, PARAM_BRANCH);
+    return branch == null
+            ? componentFinder.getByUuidOrKey(dbSession, componentId, componentKey, BASE_COMPONENT_ID_AND_KEY)
+            : componentFinder.getByKeyAndBranch(dbSession, componentKey, branch);
+  }
+
+  @CheckForNull
+  private Long searchDeveloperId(DbSession dbSession, ComponentTreeRequest wsRequest) {
+    if (wsRequest.getDeveloperId() == null && wsRequest.getDeveloperKey() == null) {
+      return null;
+    }
+
+    return componentFinder.getByUuidOrKey(dbSession, wsRequest.getDeveloperId(), wsRequest.getDeveloperKey(), DEVELOPER_ID_AND_KEY).getId();
+  }
+
+  private Map<String, ComponentDto> searchReferenceComponentsById(DbSession dbSession, List<ComponentDto> components) {
+    List<String> referenceComponentUUids = components.stream()
+            .map(ComponentDto::getCopyResourceUuid)
+            .filter(Objects::nonNull)
+            .collect(MoreCollectors.toList(components.size()));
+    if (referenceComponentUUids.isEmpty()) {
+      return emptyMap();
+    }
+
+    return FluentIterable.from(dbClient.componentDao().selectByUuids(dbSession, referenceComponentUUids))
+            .uniqueIndex(ComponentDto::uuid);
+  }
+
+  private List<ComponentDto> searchComponents(DbSession dbSession, ComponentTreeQuery componentTreeQuery) {
+    Collection<String> qualifiers = componentTreeQuery.getQualifiers();
+    if (qualifiers != null && qualifiers.isEmpty()) {
+      return Collections.emptyList();
+    }
+    return dbClient.componentDao().selectDescendants(dbSession, componentTreeQuery);
+  }
+
+  private List<MetricDto> searchMetrics(DbSession dbSession, ComponentTreeRequest request) {
+    List<String> metricKeys = requireNonNull(request.getMetricKeys());
+    List<MetricDto> metrics = dbClient.metricDao().selectByKeys(dbSession, metricKeys);
+    if (metrics.size() < metricKeys.size()) {
+      List<String> foundMetricKeys = Lists.transform(metrics, MetricDto::getKey);
+      Set<String> missingMetricKeys = Sets.difference(
+              new LinkedHashSet<>(metricKeys),
+              new LinkedHashSet<>(foundMetricKeys));
+
+      throw new NotFoundException(format("The following metric keys are not found: %s", COMMA_JOINER.join(missingMetricKeys)));
+    }
+    String forbiddenMetrics = metrics.stream()
+            .filter(metric -> ComponentTreeAction.FORBIDDEN_METRIC_TYPES.contains(metric.getValueType()))
+            .map(MetricDto::getKey)
+            .sorted()
+            .collect(MoreCollectors.join(COMMA_JOINER));
+    checkArgument(forbiddenMetrics.isEmpty(), "Metrics %s can't be requested in this web service. Please use api/measures/component", forbiddenMetrics);
+    return metrics;
+  }
+
+  private Table<String, MetricDto, ComponentTreeData.Measure> searchMeasuresByComponentUuidAndMetric(DbSession dbSession, ComponentDto baseComponent,
+    ComponentTreeQuery componentTreeQuery, List<ComponentDto> components, List<MetricDto> metrics, @Nullable Long developerId) {
+
+    Map<Integer, MetricDto> metricsById = Maps.uniqueIndex(metrics, MetricDto::getId);
+    MeasureTreeQuery measureQuery = MeasureTreeQuery.builder()
+            .setStrategy(MeasureTreeQuery.Strategy.valueOf(componentTreeQuery.getStrategy().name()))
+            .setNameOrKeyQuery(componentTreeQuery.getNameOrKeyQuery())
+            .setQualifiers(componentTreeQuery.getQualifiers())
+            .setPersonId(developerId)
+            .setMetricIds(new ArrayList<>(metricsById.keySet()))
+            .build();
+
+    Table<String, MetricDto, ComponentTreeData.Measure> measuresByComponentUuidAndMetric = HashBasedTable.create(components.size(), metrics.size());
+    dbClient.measureDao().selectTreeByQuery(dbSession, baseComponent, measureQuery, result -> {
+      MeasureDto measureDto = result.getResultObject();
+      measuresByComponentUuidAndMetric.put(
+              measureDto.getComponentUuid(),
+              metricsById.get(measureDto.getMetricId()),
+              ComponentTreeData.Measure.createFromMeasureDto(measureDto));
+    });
+
+    addBestValuesToMeasures(measuresByComponentUuidAndMetric, components, metrics);
+
+    return measuresByComponentUuidAndMetric;
+  }
+
+  /**
+   * Conditions for best value measure:
+   * <ul>
+   * <li>component is a production file or test file</li>
+   * <li>metric is optimized for best value</li>
+   * </ul>
+   */
+  private static void addBestValuesToMeasures(Table<String, MetricDto, ComponentTreeData.Measure> measuresByComponentUuidAndMetric, List<ComponentDto> components,
+                                              List<MetricDto> metrics) {
+    List<MetricDtoWithBestValue> metricDtosWithBestValueMeasure = metrics.stream()
+            .filter(MetricDtoFunctions.isOptimizedForBestValue())
+            .map(new MetricDtoToMetricDtoWithBestValue())
+            .collect(MoreCollectors.toList(metrics.size()));
+    if (metricDtosWithBestValueMeasure.isEmpty()) {
+      return;
+    }
+
+    Stream<ComponentDto> componentsEligibleForBestValue = components.stream().filter(ComponentTreeAction::isFileComponent);
+    componentsEligibleForBestValue.forEach(component -> {
+      for (MetricDtoWithBestValue metricWithBestValue : metricDtosWithBestValueMeasure) {
+        if (measuresByComponentUuidAndMetric.get(component.uuid(), metricWithBestValue.getMetric()) == null) {
+          measuresByComponentUuidAndMetric.put(component.uuid(), metricWithBestValue.getMetric(),
+                  ComponentTreeData.Measure.createFromMeasureDto(metricWithBestValue.getBestValue()));
+        }
+      }
+    });
+  }
+
+  private static List<ComponentDto> filterComponents(List<ComponentDto> components,
+    Table<String, MetricDto, ComponentTreeData.Measure> measuresByComponentUuidAndMetric, List<MetricDto> metrics, ComponentTreeRequest wsRequest) {
+    if (!componentWithMeasuresOnly(wsRequest)) {
+      return components;
+    }
+
+    String metricKeyToSort = wsRequest.getMetricSort();
+    Optional<MetricDto> metricToSort = metrics.stream().filter(m -> metricKeyToSort.equals(m.getKey())).findFirst();
+    checkState(metricToSort.isPresent(), "Metric '%s' not found", metricKeyToSort, wsRequest.getMetricKeys());
+
+    return components
+            .stream()
+            .filter(new HasMeasure(measuresByComponentUuidAndMetric, metricToSort.get(), wsRequest.getMetricPeriodSort()))
+            .collect(MoreCollectors.toList(components.size()));
+  }
+
+  private static boolean componentWithMeasuresOnly(ComponentTreeRequest wsRequest) {
+    return WITH_MEASURES_ONLY_METRIC_SORT_FILTER.equals(wsRequest.getMetricSortFilter());
+  }
+
+  private static List<ComponentDto> sortComponents(List<ComponentDto> components, ComponentTreeRequest wsRequest, List<MetricDto> metrics,
+                                                   Table<String, MetricDto, ComponentTreeData.Measure> measuresByComponentUuidAndMetric) {
+    return ComponentTreeSort.sortComponents(components, wsRequest, metrics, measuresByComponentUuidAndMetric);
+  }
+
+  private static List<ComponentDto> paginateComponents(List<ComponentDto> components, ComponentTreeRequest wsRequest) {
+    return components.stream()
+            .skip(offset(wsRequest.getPage(), wsRequest.getPageSize()))
+            .limit(wsRequest.getPageSize())
+            .collect(MoreCollectors.toList(wsRequest.getPageSize()));
+  }
+
+  @CheckForNull
+  private List<String> childrenQualifiers(ComponentTreeRequest request, String baseQualifier) {
+    List<String> requestQualifiers = request.getQualifiers();
+    List<String> childrenQualifiers = null;
+    if (LEAVES_STRATEGY.equals(request.getStrategy())) {
+      childrenQualifiers = resourceTypes.getLeavesQualifiers(baseQualifier);
+    }
+
+    if (requestQualifiers == null) {
+      return childrenQualifiers;
+    }
+
+    if (childrenQualifiers == null) {
+      return requestQualifiers;
+    }
+
+    Sets.SetView<String> qualifiersIntersection = Sets.intersection(new HashSet<>(childrenQualifiers), new HashSet<Object>(requestQualifiers));
+
+    return new ArrayList<>(qualifiersIntersection);
+  }
+
+  private ComponentTreeQuery toComponentTreeQuery(ComponentTreeRequest wsRequest, ComponentDto baseComponent) {
+    List<String> childrenQualifiers = childrenQualifiers(wsRequest, baseComponent.qualifier());
+
+    ComponentTreeQuery.Builder componentTreeQueryBuilder = ComponentTreeQuery.builder()
+            .setBaseUuid(baseComponent.uuid())
+            .setStrategy(STRATEGIES.get(wsRequest.getStrategy()));
+
+    if (wsRequest.getQuery() != null) {
+      componentTreeQueryBuilder.setNameOrKeyQuery(wsRequest.getQuery());
+    }
+    if (childrenQualifiers != null) {
+      componentTreeQueryBuilder.setQualifiers(childrenQualifiers);
+    }
+    return componentTreeQueryBuilder.build();
+  }
+
+  private void checkPermissions(ComponentDto baseComponent) {
+    userSession.checkComponentPermission(UserRole.USER, baseComponent);
+  }
+
+  public static boolean isFileComponent(@Nonnull ComponentDto input) {
+    return QUALIFIERS_ELIGIBLE_FOR_BEST_VALUE.contains(input.qualifier());
+  }
+
+  private static class MetricDtoToMetricDtoWithBestValue implements Function<MetricDto, MetricDtoWithBestValue> {
+    @Override
+    public MetricDtoWithBestValue apply(@Nonnull MetricDto input) {
+      return new MetricDtoWithBestValue(input);
+    }
+  }
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java
deleted file mode 100644 (file)
index fc2dba8..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.measure.ws;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.collect.Table;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.stream.Stream;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.ResourceTypes;
-import org.sonar.api.web.UserRole;
-import org.sonar.core.util.stream.MoreCollectors;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTreeQuery;
-import org.sonar.db.component.SnapshotDto;
-import org.sonar.db.measure.MeasureDto;
-import org.sonar.db.measure.MeasureTreeQuery;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.db.metric.MetricDtoFunctions;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.measure.ws.ComponentTreeData.Measure;
-import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.measure.ComponentTreeRequest;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-import static java.lang.String.format;
-import static java.util.Collections.emptyMap;
-import static java.util.Objects.requireNonNull;
-import static org.sonar.api.utils.Paging.offset;
-import static org.sonar.server.component.ComponentFinder.ParamNames.BASE_COMPONENT_ID_AND_KEY;
-import static org.sonar.server.component.ComponentFinder.ParamNames.DEVELOPER_ID_AND_KEY;
-import static org.sonar.server.measure.ws.ComponentTreeAction.LEAVES_STRATEGY;
-import static org.sonar.server.measure.ws.ComponentTreeAction.STRATEGIES;
-import static org.sonar.server.measure.ws.ComponentTreeAction.WITH_MEASURES_ONLY_METRIC_SORT_FILTER;
-import static org.sonar.server.measure.ws.SnapshotDtoToWsPeriods.snapshotToWsPeriods;
-import static org.sonarqube.ws.client.measure.MeasuresWsParameters.DEPRECATED_PARAM_BASE_COMPONENT_ID;
-import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BRANCH;
-
-public class ComponentTreeDataLoader {
-  private static final Set<String> QUALIFIERS_ELIGIBLE_FOR_BEST_VALUE = ImmutableSet.of(Qualifiers.FILE, Qualifiers.UNIT_TEST_FILE);
-  private static final Joiner COMA_JOINER = Joiner.on(", ");
-
-  private final DbClient dbClient;
-  private final ComponentFinder componentFinder;
-  private final UserSession userSession;
-  private final ResourceTypes resourceTypes;
-
-  public ComponentTreeDataLoader(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, ResourceTypes resourceTypes) {
-    this.dbClient = dbClient;
-    this.componentFinder = componentFinder;
-    this.userSession = userSession;
-    this.resourceTypes = resourceTypes;
-  }
-
-  ComponentTreeData load(ComponentTreeRequest wsRequest) {
-    try (DbSession dbSession = dbClient.openSession(false)) {
-      ComponentDto baseComponent = loadComponent(dbSession, wsRequest);
-      checkPermissions(baseComponent);
-      Optional<SnapshotDto> baseSnapshot = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(dbSession, baseComponent.projectUuid());
-      if (!baseSnapshot.isPresent()) {
-        return ComponentTreeData.builder()
-          .setBaseComponent(baseComponent)
-          .build();
-      }
-      Long developerId = searchDeveloperId(dbSession, wsRequest);
-
-      ComponentTreeQuery componentTreeQuery = toComponentTreeQuery(wsRequest, baseComponent);
-      List<ComponentDto> components = searchComponents(dbSession, componentTreeQuery);
-      List<MetricDto> metrics = searchMetrics(dbSession, wsRequest);
-      Table<String, MetricDto, Measure> measuresByComponentUuidAndMetric = searchMeasuresByComponentUuidAndMetric(dbSession, baseComponent, componentTreeQuery,
-        components,
-        metrics, developerId);
-
-      components = filterComponents(components, measuresByComponentUuidAndMetric, metrics, wsRequest);
-      components = sortComponents(components, wsRequest, metrics, measuresByComponentUuidAndMetric);
-
-      int componentCount = components.size();
-      components = paginateComponents(components, wsRequest);
-
-      return ComponentTreeData.builder()
-        .setBaseComponent(baseComponent)
-        .setComponentsFromDb(components)
-        .setComponentCount(componentCount)
-        .setMeasuresByComponentUuidAndMetric(measuresByComponentUuidAndMetric)
-        .setMetrics(metrics)
-        .setPeriods(snapshotToWsPeriods(baseSnapshot.get()))
-        .setReferenceComponentsByUuid(searchReferenceComponentsById(dbSession, components))
-        .build();
-    }
-  }
-
-  private ComponentDto loadComponent(DbSession dbSession, ComponentTreeRequest request) {
-    String componentKey = request.getComponent();
-    String componentId = request.getBaseComponentId();
-    String branch = request.getBranch();
-    checkArgument(componentId == null || branch == null, "'%s' and '%s' parameters cannot be used at the same time", DEPRECATED_PARAM_BASE_COMPONENT_ID, PARAM_BRANCH);
-    return branch == null
-      ? componentFinder.getByUuidOrKey(dbSession, componentId, componentKey, BASE_COMPONENT_ID_AND_KEY)
-      : componentFinder.getByKeyAndBranch(dbSession, componentKey, branch);
-  }
-
-  @CheckForNull
-  private Long searchDeveloperId(DbSession dbSession, ComponentTreeRequest wsRequest) {
-    if (wsRequest.getDeveloperId() == null && wsRequest.getDeveloperKey() == null) {
-      return null;
-    }
-
-    return componentFinder.getByUuidOrKey(dbSession, wsRequest.getDeveloperId(), wsRequest.getDeveloperKey(), DEVELOPER_ID_AND_KEY).getId();
-  }
-
-  private Map<String, ComponentDto> searchReferenceComponentsById(DbSession dbSession, List<ComponentDto> components) {
-    List<String> referenceComponentUUids = components.stream()
-      .map(ComponentDto::getCopyResourceUuid)
-      .filter(Objects::nonNull)
-      .collect(MoreCollectors.toList(components.size()));
-    if (referenceComponentUUids.isEmpty()) {
-      return emptyMap();
-    }
-
-    return FluentIterable.from(dbClient.componentDao().selectByUuids(dbSession, referenceComponentUUids))
-      .uniqueIndex(ComponentDto::uuid);
-  }
-
-  private List<ComponentDto> searchComponents(DbSession dbSession, ComponentTreeQuery componentTreeQuery) {
-    Collection<String> qualifiers = componentTreeQuery.getQualifiers();
-    if (qualifiers != null && qualifiers.isEmpty()) {
-      return Collections.emptyList();
-    }
-    return dbClient.componentDao().selectDescendants(dbSession, componentTreeQuery);
-  }
-
-  private List<MetricDto> searchMetrics(DbSession dbSession, ComponentTreeRequest request) {
-    List<String> metricKeys = requireNonNull(request.getMetricKeys());
-    List<MetricDto> metrics = dbClient.metricDao().selectByKeys(dbSession, metricKeys);
-    if (metrics.size() < metricKeys.size()) {
-      List<String> foundMetricKeys = Lists.transform(metrics, MetricDto::getKey);
-      Set<String> missingMetricKeys = Sets.difference(
-        new LinkedHashSet<>(metricKeys),
-        new LinkedHashSet<>(foundMetricKeys));
-
-      throw new NotFoundException(format("The following metric keys are not found: %s", COMA_JOINER.join(missingMetricKeys)));
-    }
-    String forbiddenMetrics = metrics.stream()
-      .filter(metric -> ComponentTreeAction.FORBIDDEN_METRIC_TYPES.contains(metric.getValueType()))
-      .map(MetricDto::getKey)
-      .sorted()
-      .collect(MoreCollectors.join(COMA_JOINER));
-    checkArgument(forbiddenMetrics.isEmpty(), "Metrics %s can't be requested in this web service. Please use api/measures/component", forbiddenMetrics);
-    return metrics;
-  }
-
-  private Table<String, MetricDto, Measure> searchMeasuresByComponentUuidAndMetric(DbSession dbSession, ComponentDto baseComponent,
-    ComponentTreeQuery componentTreeQuery,
-    List<ComponentDto> components, List<MetricDto> metrics, @Nullable Long developerId) {
-
-    Map<Integer, MetricDto> metricsById = Maps.uniqueIndex(metrics, MetricDto::getId);
-    MeasureTreeQuery measureQuery = MeasureTreeQuery.builder()
-      .setStrategy(MeasureTreeQuery.Strategy.valueOf(componentTreeQuery.getStrategy().name()))
-      .setNameOrKeyQuery(componentTreeQuery.getNameOrKeyQuery())
-      .setQualifiers(componentTreeQuery.getQualifiers())
-      .setPersonId(developerId)
-      .setMetricIds(new ArrayList<>(metricsById.keySet()))
-      .build();
-
-    Table<String, MetricDto, Measure> measuresByComponentUuidAndMetric = HashBasedTable.create(components.size(), metrics.size());
-    dbClient.measureDao().selectTreeByQuery(dbSession, baseComponent, measureQuery, result -> {
-      MeasureDto measureDto = result.getResultObject();
-      measuresByComponentUuidAndMetric.put(
-        measureDto.getComponentUuid(),
-        metricsById.get(measureDto.getMetricId()),
-        Measure.createFromMeasureDto(measureDto));
-    });
-
-    addBestValuesToMeasures(measuresByComponentUuidAndMetric, components, metrics);
-
-    return measuresByComponentUuidAndMetric;
-  }
-
-  /**
-   * Conditions for best value measure:
-   * <ul>
-   * <li>component is a production file or test file</li>
-   * <li>metric is optimized for best value</li>
-   * </ul>
-   */
-  private static void addBestValuesToMeasures(Table<String, MetricDto, Measure> measuresByComponentUuidAndMetric, List<ComponentDto> components,
-    List<MetricDto> metrics) {
-    List<MetricDtoWithBestValue> metricDtosWithBestValueMeasure = metrics.stream()
-      .filter(MetricDtoFunctions.isOptimizedForBestValue())
-      .map(new MetricDtoToMetricDtoWithBestValue())
-      .collect(MoreCollectors.toList(metrics.size()));
-    if (metricDtosWithBestValueMeasure.isEmpty()) {
-      return;
-    }
-
-    Stream<ComponentDto> componentsEligibleForBestValue = components.stream().filter(IsFileComponent.INSTANCE);
-    componentsEligibleForBestValue.forEach(component -> {
-      for (MetricDtoWithBestValue metricWithBestValue : metricDtosWithBestValueMeasure) {
-        if (measuresByComponentUuidAndMetric.get(component.uuid(), metricWithBestValue.getMetric()) == null) {
-          measuresByComponentUuidAndMetric.put(component.uuid(), metricWithBestValue.getMetric(),
-            Measure.createFromMeasureDto(metricWithBestValue.getBestValue()));
-        }
-      }
-    });
-  }
-
-  private static List<ComponentDto> filterComponents(List<ComponentDto> components,
-    Table<String, MetricDto, Measure> measuresByComponentUuidAndMetric, List<MetricDto> metrics, ComponentTreeRequest wsRequest) {
-    if (!componentWithMeasuresOnly(wsRequest)) {
-      return components;
-    }
-
-    String metricKeyToSort = wsRequest.getMetricSort();
-    Optional<MetricDto> metricToSort = metrics.stream().filter(m -> metricKeyToSort.equals(m.getKey())).findFirst();
-    checkState(metricToSort.isPresent(), "Metric '%s' not found", metricKeyToSort, wsRequest.getMetricKeys());
-
-    return components
-      .stream()
-      .filter(new HasMeasure(measuresByComponentUuidAndMetric, metricToSort.get(), wsRequest))
-      .collect(MoreCollectors.toList(components.size()));
-  }
-
-  private static boolean componentWithMeasuresOnly(ComponentTreeRequest wsRequest) {
-    return WITH_MEASURES_ONLY_METRIC_SORT_FILTER.equals(wsRequest.getMetricSortFilter());
-  }
-
-  private static List<ComponentDto> sortComponents(List<ComponentDto> components, ComponentTreeRequest wsRequest, List<MetricDto> metrics,
-                                                   Table<String, MetricDto, Measure> measuresByComponentUuidAndMetric) {
-    return ComponentTreeSort.sortComponents(components, wsRequest, metrics, measuresByComponentUuidAndMetric);
-  }
-
-  private static List<ComponentDto> paginateComponents(List<ComponentDto> components, ComponentTreeRequest wsRequest) {
-    return components.stream()
-      .skip(offset(wsRequest.getPage(), wsRequest.getPageSize()))
-      .limit(wsRequest.getPageSize())
-      .collect(MoreCollectors.toList(wsRequest.getPageSize()));
-  }
-
-  @CheckForNull
-  private List<String> childrenQualifiers(ComponentTreeRequest request, String baseQualifier) {
-    List<String> requestQualifiers = request.getQualifiers();
-    List<String> childrenQualifiers = null;
-    if (LEAVES_STRATEGY.equals(request.getStrategy())) {
-      childrenQualifiers = resourceTypes.getLeavesQualifiers(baseQualifier);
-    }
-
-    if (requestQualifiers == null) {
-      return childrenQualifiers;
-    }
-
-    if (childrenQualifiers == null) {
-      return requestQualifiers;
-    }
-
-    Sets.SetView<String> qualifiersIntersection = Sets.intersection(new HashSet<>(childrenQualifiers), new HashSet<Object>(requestQualifiers));
-
-    return new ArrayList<>(qualifiersIntersection);
-  }
-
-  private ComponentTreeQuery toComponentTreeQuery(ComponentTreeRequest wsRequest, ComponentDto baseComponent) {
-    List<String> childrenQualifiers = childrenQualifiers(wsRequest, baseComponent.qualifier());
-
-    ComponentTreeQuery.Builder componentTreeQueryBuilder = ComponentTreeQuery.builder()
-      .setBaseUuid(baseComponent.uuid())
-      .setStrategy(STRATEGIES.get(wsRequest.getStrategy()));
-
-    if (wsRequest.getQuery() != null) {
-      componentTreeQueryBuilder.setNameOrKeyQuery(wsRequest.getQuery());
-    }
-    if (childrenQualifiers != null) {
-      componentTreeQueryBuilder.setQualifiers(childrenQualifiers);
-    }
-    return componentTreeQueryBuilder.build();
-  }
-
-  private void checkPermissions(ComponentDto baseComponent) {
-    userSession.checkComponentPermission(UserRole.USER, baseComponent);
-  }
-
-  private enum IsFileComponent implements Predicate<ComponentDto> {
-    INSTANCE;
-
-    @Override
-    public boolean test(@Nonnull ComponentDto input) {
-      return QUALIFIERS_ELIGIBLE_FOR_BEST_VALUE.contains(input.qualifier());
-    }
-  }
-
-  private static class MetricDtoToMetricDtoWithBestValue implements Function<MetricDto, MetricDtoWithBestValue> {
-    @Override
-    public MetricDtoWithBestValue apply(@Nonnull MetricDto input) {
-      return new MetricDtoWithBestValue(input);
-    }
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeRequest.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeRequest.java
new file mode 100644 (file)
index 0000000..909a133
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.measure.ws;
+
+import java.util.List;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+class ComponentTreeRequest {
+
+  private String baseComponentId;
+  private String baseComponentKey;
+  private String component;
+  private String branch;
+  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 Integer metricPeriodSort;
+  private String metricSortFilter;
+  private List<String> metricKeys;
+  private Integer page;
+  private Integer pageSize;
+  private String developerId;
+  private String developerKey;
+
+  /**
+   * @deprecated since 6.6, please use {@link #getComponent()} instead
+   */
+  @Deprecated
+  @CheckForNull
+  public String getBaseComponentId() {
+    return baseComponentId;
+  }
+
+  /**
+   * @deprecated since 6.6, please use {@link #setComponent(String)} instead
+   */
+  @Deprecated
+  public ComponentTreeRequest setBaseComponentId(@Nullable String baseComponentId) {
+    this.baseComponentId = baseComponentId;
+    return this;
+  }
+
+  @CheckForNull
+  public String getComponent() {
+    return component;
+  }
+
+  public ComponentTreeRequest setComponent(@Nullable String component) {
+    this.component = component;
+    return this;
+  }
+
+  @CheckForNull
+  public String getBranch() {
+    return branch;
+  }
+
+  public ComponentTreeRequest setBranch(@Nullable String branch) {
+    this.branch = branch;
+    return this;
+  }
+
+  @CheckForNull
+  public String getStrategy() {
+    return strategy;
+  }
+
+  public ComponentTreeRequest setStrategy(String strategy) {
+    this.strategy = strategy;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getQualifiers() {
+    return qualifiers;
+  }
+
+  public ComponentTreeRequest setQualifiers(@Nullable List<String> qualifiers) {
+    this.qualifiers = qualifiers;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getAdditionalFields() {
+    return additionalFields;
+  }
+
+  public ComponentTreeRequest setAdditionalFields(@Nullable List<String> additionalFields) {
+    this.additionalFields = additionalFields;
+    return this;
+  }
+
+  @CheckForNull
+  public String getQuery() {
+    return query;
+  }
+
+  public ComponentTreeRequest setQuery(@Nullable String query) {
+    this.query = query;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getSort() {
+    return sort;
+  }
+
+  public ComponentTreeRequest setSort(@Nullable List<String> sort) {
+    this.sort = sort;
+    return this;
+  }
+
+  @CheckForNull
+  public String getMetricSort() {
+    return metricSort;
+  }
+
+  public ComponentTreeRequest setMetricSort(@Nullable String metricSort) {
+    this.metricSort = metricSort;
+    return this;
+  }
+
+  @CheckForNull
+  public String getMetricSortFilter() {
+    return metricSortFilter;
+  }
+
+  public ComponentTreeRequest setMetricSortFilter(@Nullable String metricSortFilter) {
+    this.metricSortFilter = metricSortFilter;
+    return this;
+  }
+
+  @CheckForNull
+  public List<String> getMetricKeys() {
+    return metricKeys;
+  }
+
+  public ComponentTreeRequest setMetricKeys(List<String> metricKeys) {
+    this.metricKeys = metricKeys;
+    return this;
+  }
+
+  @CheckForNull
+  public Boolean getAsc() {
+    return asc;
+  }
+
+  public ComponentTreeRequest setAsc(@Nullable Boolean asc) {
+    this.asc = asc;
+    return this;
+  }
+
+  @CheckForNull
+  public Integer getPage() {
+    return page;
+  }
+
+  public ComponentTreeRequest setPage(int page) {
+    this.page = page;
+    return this;
+  }
+
+  @CheckForNull
+  public Integer getPageSize() {
+    return pageSize;
+  }
+
+  public ComponentTreeRequest setPageSize(int pageSize) {
+    this.pageSize = pageSize;
+    return this;
+  }
+
+  @CheckForNull
+  public Integer getMetricPeriodSort() {
+    return metricPeriodSort;
+  }
+
+  public ComponentTreeRequest setMetricPeriodSort(@Nullable Integer metricPeriodSort) {
+    this.metricPeriodSort = metricPeriodSort;
+    return this;
+  }
+
+  @CheckForNull
+  public String getDeveloperId() {
+    return developerId;
+  }
+
+  public ComponentTreeRequest setDeveloperId(@Nullable String developerId) {
+    this.developerId = developerId;
+    return this;
+  }
+
+  @CheckForNull
+  public String getDeveloperKey() {
+    return developerKey;
+  }
+
+  public ComponentTreeRequest setDeveloperKey(@Nullable String developerKey) {
+    this.developerKey = developerKey;
+    return this;
+  }
+}
index cf881dd6126986bdb51c0585ed079725b2479ee7..28ac65e7091b02dfa48699c31204d9ce7de3eb6c 100644 (file)
@@ -35,7 +35,6 @@ import org.sonar.api.measures.Metric.ValueType;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.metric.MetricDto;
 import org.sonar.server.exceptions.BadRequestException;
-import org.sonarqube.ws.client.measure.ComponentTreeRequest;
 
 import static java.lang.String.CASE_INSENSITIVE_ORDER;
 import static java.lang.String.format;
index 3f0b7ed5bdbdc8b39ebaa6dafa14f79c4391bf87..6db3622a14f39e892454fe37b2cec3b10d8be809 100644 (file)
@@ -22,18 +22,18 @@ package org.sonar.server.measure.ws;
 import com.google.common.collect.Table;
 import java.util.function.Predicate;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.metric.MetricDto;
-import org.sonarqube.ws.client.measure.ComponentTreeRequest;
 
 import static org.sonar.server.measure.ws.ComponentTreeData.Measure;
 
 class HasMeasure implements Predicate<ComponentDto> {
   private final Predicate<ComponentDto> predicate;
 
-  HasMeasure(Table<String, MetricDto, ComponentTreeData.Measure> table, MetricDto metric, ComponentTreeRequest request) {
-    Integer periodIndex = request.getMetricPeriodSort();
-    this.predicate = periodIndex == null
+  HasMeasure(Table<String, MetricDto, ComponentTreeData.Measure> table, MetricDto metric, @Nullable Integer metricPeriodSort) {
+    this.predicate = metricPeriodSort == null
       ? new HasAbsoluteValue(table, metric)
       : new HasValueOnPeriod(table, metric);
   }
index e4b098e66df03b7cd32d88e5f1ad259dc2550f8b..651c4916c0ecd440748c76ed7d88f1331a0c994b 100644 (file)
@@ -25,7 +25,6 @@ public class MeasuresWsModule extends Module {
   @Override
   protected void configureModule() {
     add(
-      ComponentTreeDataLoader.class,
       MeasuresWs.class,
       ComponentTreeAction.class,
       ComponentAction.class,
index 27672b442e41e08fdbbba338f9088169b85d8ec2..dbbda02517f4465fcd117cf649f2749ce2457bb6 100644 (file)
@@ -39,7 +39,6 @@ import org.sonar.db.metric.MetricDto;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Measures.Measure;
 import org.sonarqube.ws.Measures.SearchWsResponse;
-import org.sonarqube.ws.client.measure.SearchRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Comparator.comparing;
@@ -61,6 +60,7 @@ import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_PROJECT
 
 public class SearchAction implements MeasuresWsAction {
 
+  private static final int MAX_NB_PROJECTS = 100;
   private static final Set<String> ALLOWED_QUALIFIERS = ImmutableSet.of(PROJECT, APP, VIEW, SUBVIEW);
 
   private final UserSession userSession;
@@ -78,7 +78,7 @@ public class SearchAction implements MeasuresWsAction {
       .setDescription("Search for project measures ordered by project names.<br>" +
         "At most %d projects can be provided.<br>" +
         "Returns the projects with the 'Browse' permission.",
-        SearchRequest.MAX_NB_PROJECTS)
+        MAX_NB_PROJECTS)
       .setSince("6.2")
       .setResponseExample(getClass().getResource("search-example.json"))
       .setHandler(this);
@@ -196,4 +196,56 @@ public class SearchAction implements MeasuresWsAction {
         .collect(toList());
     }
   }
+
+  private static class SearchRequest {
+
+    private final List<String> metricKeys;
+    private final List<String> projectKeys;
+
+    public SearchRequest(Builder builder) {
+      metricKeys = builder.metricKeys;
+      projectKeys = builder.projectKeys;
+    }
+
+    public List<String> getMetricKeys() {
+      return metricKeys;
+    }
+
+    public List<String> getProjectKeys() {
+      return projectKeys;
+    }
+
+    public static Builder builder() {
+      return new Builder();
+    }
+
+  }
+
+  private static class Builder {
+    private List<String> metricKeys;
+    private List<String> projectKeys;
+
+    private Builder() {
+      // enforce method constructor
+    }
+
+    public Builder setMetricKeys(List<String> metricKeys) {
+      this.metricKeys = metricKeys;
+      return this;
+    }
+
+    public Builder setProjectKeys(List<String> projectKeys) {
+      this.projectKeys = projectKeys;
+      return this;
+    }
+
+    public SearchAction.SearchRequest build() {
+      checkArgument(metricKeys != null && !metricKeys.isEmpty(), "Metric keys must be provided");
+      checkArgument(projectKeys != null && !projectKeys.isEmpty(), "Project keys must be provided");
+      int nbComponents = projectKeys.size();
+      checkArgument(nbComponents <= MAX_NB_PROJECTS,
+              "%s projects provided, more than maximum authorized (%s)", nbComponents, MAX_NB_PROJECTS);
+      return new SearchAction.SearchRequest(this);
+    }
+  }
 }
index f2e4ac957484d1dbf7575ef49caf30b4e9a62e32..c76decf679247487fdf4e2656c47853cfd65dedd 100644 (file)
@@ -45,7 +45,9 @@ import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.user.UserSession;
 import org.sonar.server.ws.KeyExamples;
 import org.sonarqube.ws.Measures.SearchHistoryResponse;
-import org.sonarqube.ws.client.measure.SearchHistoryRequest;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 
 import static java.lang.String.format;
 import static org.sonar.api.utils.DateUtils.parseEndingDateOrDateTime;
@@ -60,10 +62,12 @@ import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_COMPONE
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_FROM;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRICS;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_TO;
-import static org.sonarqube.ws.client.measure.SearchHistoryRequest.DEFAULT_PAGE_SIZE;
-import static org.sonarqube.ws.client.measure.SearchHistoryRequest.MAX_PAGE_SIZE;
 
 public class SearchHistoryAction implements MeasuresWsAction {
+
+  private static final int MAX_PAGE_SIZE = 1_000;
+  private static final int DEFAULT_PAGE_SIZE = 100;
+
   private final DbClient dbClient;
   private final ComponentFinder componentFinder;
   private final UserSession userSession;
@@ -142,7 +146,7 @@ public class SearchHistoryAction implements MeasuresWsAction {
       try (DbSession dbSession = dbClient.openSession(false)) {
         ComponentDto component = searchComponent(request, dbSession);
 
-        SearchHistoryResult result = new SearchHistoryResult(request)
+        SearchHistoryResult result = new SearchHistoryResult(request.page, request.pageSize)
           .setComponent(component)
           .setAnalyses(searchAnalyses(dbSession, request, component))
           .setMetrics(searchMetrics(dbSession, request));
@@ -201,4 +205,121 @@ public class SearchHistoryAction implements MeasuresWsAction {
     return componentFinder.getByKey(dbSession, componentKey);
   }
 
+  static class SearchHistoryRequest {
+    private final String component;
+    private final String branch;
+    private final List<String> metrics;
+    private final String from;
+    private final String to;
+    private final int page;
+    private final int pageSize;
+
+    public SearchHistoryRequest(Builder builder) {
+      this.component = builder.component;
+      this.branch = builder.branch;
+      this.metrics = builder.metrics;
+      this.from = builder.from;
+      this.to = builder.to;
+      this.page = builder.page;
+      this.pageSize = builder.pageSize;
+    }
+
+    public String getComponent() {
+      return component;
+    }
+
+    @CheckForNull
+    public String getBranch() {
+      return branch;
+    }
+
+    public List<String> getMetrics() {
+      return metrics;
+    }
+
+    @CheckForNull
+    public String getFrom() {
+      return from;
+    }
+
+    @CheckForNull
+    public String getTo() {
+      return to;
+    }
+
+    public int getPage() {
+      return page;
+    }
+
+    public int getPageSize() {
+      return pageSize;
+    }
+
+    public static Builder builder() {
+      return new Builder();
+    }
+  }
+
+  static class Builder {
+    private String component;
+    private String branch;
+    private List<String> metrics;
+    private String from;
+    private String to;
+    private int page = 1;
+    private int pageSize = DEFAULT_PAGE_SIZE;
+
+    private Builder() {
+      // enforce build factory method
+    }
+
+    public Builder setComponent(String component) {
+      this.component = component;
+      return this;
+    }
+
+    public Builder setBranch(@Nullable String branch) {
+      this.branch = branch;
+      return this;
+    }
+
+    public Builder setMetrics(List<String> metrics) {
+      this.metrics = metrics;
+      return this;
+    }
+
+    public Builder setFrom(@Nullable String from) {
+      this.from = from;
+      return this;
+    }
+
+    public Builder setTo(@Nullable String to) {
+      this.to = to;
+      return this;
+    }
+
+    public Builder setPage(int page) {
+      this.page = page;
+      return this;
+    }
+
+    public Builder setPageSize(int pageSize) {
+      this.pageSize = pageSize;
+      return this;
+    }
+
+    public SearchHistoryRequest build() {
+      checkArgument(component != null && !component.isEmpty(), "Component key is required");
+      checkArgument(metrics != null && !metrics.isEmpty(), "Metric keys are required");
+      checkArgument(pageSize <= MAX_PAGE_SIZE, "Page size (%d) must be lower than or equal to %d", pageSize, MAX_PAGE_SIZE);
+
+      return new SearchHistoryRequest(this);
+    }
+
+    private static void checkArgument(boolean condition, String message, Object... args) {
+      if (!condition) {
+        throw new IllegalArgumentException(format(message, args));
+      }
+    }
+  }
 }
index 22d7440bbd0998b65c23d1955ca59f92f35e69a4..9b0cc84cacc97624393e72fc8dab9e33e3af0f96 100644 (file)
@@ -31,7 +31,6 @@ import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.measure.MeasureDto;
 import org.sonar.db.metric.MetricDto;
 import org.sonarqube.ws.Common;
-import org.sonarqube.ws.client.measure.SearchHistoryRequest;
 
 import static java.util.Collections.emptyList;
 import static java.util.Objects.requireNonNull;
@@ -40,15 +39,17 @@ import static org.sonar.db.metric.MetricDtoFunctions.isOptimizedForBestValue;
 import static org.sonar.server.measure.ws.MetricDtoWithBestValue.isEligibleForBestValue;
 
 class SearchHistoryResult {
-  private final SearchHistoryRequest request;
+  private final int page;
+  private final int pageSize;
   private List<SnapshotDto> analyses;
   private List<MetricDto> metrics;
   private List<MeasureDto> measures;
   private Common.Paging paging;
   private ComponentDto component;
 
-  SearchHistoryResult(SearchHistoryRequest request) {
-    this.request = request;
+  SearchHistoryResult(int page, int pageSize) {
+    this.page = page;
+    this.pageSize = pageSize;
   }
 
   public ComponentDto getComponent() {
@@ -66,8 +67,8 @@ class SearchHistoryResult {
   }
 
   SearchHistoryResult setAnalyses(List<SnapshotDto> analyses) {
-    this.paging = Common.Paging.newBuilder().setPageIndex(request.getPage()).setPageSize(request.getPageSize()).setTotal(analyses.size()).build();
-    this.analyses = analyses.stream().skip(offset(request.getPage(), request.getPageSize())).limit(request.getPageSize()).collect(MoreCollectors.toList());
+    this.paging = Common.Paging.newBuilder().setPageIndex(page).setPageSize(pageSize).setTotal(analyses.size()).build();
+    this.analyses = analyses.stream().skip(offset(page, pageSize)).limit(pageSize).collect(MoreCollectors.toList());
 
     return this;
   }
index 4fac5363b7092c34d656db5b3b83e4b4ec007fff..49ae0dda65133b9bcdb5d4c1c86f203f4bbefce4 100644 (file)
@@ -39,7 +39,6 @@ import org.sonar.server.notification.NotificationUpdater;
 import org.sonar.server.notification.email.EmailNotificationChannel;
 import org.sonar.server.user.UserSession;
 import org.sonar.server.ws.KeyExamples;
-import org.sonarqube.ws.client.notifications.AddRequest;
 
 import static java.util.Optional.empty;
 import static org.sonar.core.util.Protobuf.setNullable;
@@ -172,4 +171,48 @@ public class AddAction implements NotificationsWsAction {
 
     return add;
   }
+
+  private static class AddRequest {
+
+    private String channel;
+    private String login;
+    private String project;
+    private String type;
+
+    public AddRequest setChannel(String channel) {
+      this.channel = channel;
+      return this;
+    }
+
+    public String getChannel() {
+      return channel;
+    }
+
+    public AddRequest setLogin(String login) {
+      this.login = login;
+      return this;
+    }
+
+    public String getLogin() {
+      return login;
+    }
+
+    public AddRequest setProject(String project) {
+      this.project = project;
+      return this;
+    }
+
+    public String getProject() {
+      return project;
+    }
+
+    public AddRequest setType(String type) {
+      this.type = type;
+      return this;
+    }
+
+    public String getType() {
+      return type;
+    }
+  }
 }
index b8cd0a79ed2bfcf91a863426b6ce1b4d67101019..d866cf20543c6e01318a6f4eec1c9aaef7561dde 100644 (file)
@@ -39,7 +39,6 @@ import org.sonar.server.notification.NotificationUpdater;
 import org.sonar.server.notification.email.EmailNotificationChannel;
 import org.sonar.server.user.UserSession;
 import org.sonar.server.ws.KeyExamples;
-import org.sonarqube.ws.client.notifications.RemoveRequest;
 
 import static java.util.Optional.empty;
 import static org.sonar.core.util.Protobuf.setNullable;
@@ -170,4 +169,48 @@ public class RemoveAction implements NotificationsWsAction {
 
     return remove;
   }
+
+  static class RemoveRequest {
+
+    private String channel;
+    private String login;
+    private String project;
+    private String type;
+
+    public RemoveRequest setChannel(String channel) {
+      this.channel = channel;
+      return this;
+    }
+
+    public String getChannel() {
+      return channel;
+    }
+
+    public RemoveRequest setLogin(String login) {
+      this.login = login;
+      return this;
+    }
+
+    public String getLogin() {
+      return login;
+    }
+
+    public RemoveRequest setProject(String project) {
+      this.project = project;
+      return this;
+    }
+
+    public String getProject() {
+      return project;
+    }
+
+    public RemoveRequest setType(String type) {
+      this.type = type;
+      return this;
+    }
+
+    public String getType() {
+      return type;
+    }
+  }
 }
index f32b3f49a6e794a5a8eae8870435fb7ed138640a..9407c73b4e426d440f2cc58fe9029e4ae2474a99 100644 (file)
@@ -31,7 +31,6 @@ import org.sonar.server.permission.ws.template.RemoveGroupFromTemplateAction;
 import org.sonar.server.permission.ws.template.RemoveProjectCreatorFromTemplateAction;
 import org.sonar.server.permission.ws.template.RemoveUserFromTemplateAction;
 import org.sonar.server.permission.ws.template.SearchTemplatesAction;
-import org.sonar.server.permission.ws.template.SearchTemplatesDataLoader;
 import org.sonar.server.permission.ws.template.SetDefaultTemplateAction;
 import org.sonar.server.permission.ws.template.TemplateGroupsAction;
 import org.sonar.server.permission.ws.template.TemplateUsersAction;
@@ -67,8 +66,6 @@ public class PermissionsWsModule extends Module {
       TemplateGroupsAction.class,
       BulkApplyTemplateAction.class,
       // utility classes
-      SearchProjectPermissionsDataLoader.class,
-      SearchTemplatesDataLoader.class,
       PermissionWsSupport.class);
   }
 }
index 2eb7531c944e4bdc77d26d223547b7ed2e1ddede..dea8bfc6f228e4d9a60b7e7822588ea19a17f288 100644 (file)
  */
 package org.sonar.server.permission.ws;
 
+import java.util.List;
 import java.util.Locale;
 import java.util.Optional;
+
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Table;
+import com.google.common.collect.TreeBasedTable;
 import org.sonar.api.i18n.I18n;
+import org.sonar.api.resources.ResourceType;
 import org.sonar.api.resources.ResourceTypes;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
@@ -32,6 +39,8 @@ import org.sonar.core.permission.ProjectPermissions;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentQuery;
+import org.sonar.db.permission.CountPerProjectPermission;
 import org.sonar.server.permission.PermissionPrivilegeChecker;
 import org.sonar.server.permission.ProjectId;
 import org.sonar.server.user.UserSession;
@@ -39,11 +48,16 @@ import org.sonarqube.ws.Common;
 import org.sonarqube.ws.Permissions.Permission;
 import org.sonarqube.ws.Permissions.SearchProjectPermissionsWsResponse;
 import org.sonarqube.ws.Permissions.SearchProjectPermissionsWsResponse.Project;
-import org.sonarqube.ws.client.permission.SearchProjectPermissionsRequest;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import static java.util.Collections.singletonList;
+import static org.sonar.api.utils.Paging.forPageIndex;
 import static org.sonar.server.permission.ws.PermissionRequestValidator.validateQualifier;
 import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters;
 import static org.sonar.server.permission.ws.ProjectWsRef.newOptionalWsProjectRef;
+import static org.sonar.server.permission.ws.SearchProjectPermissionsData.newBuilder;
 import static org.sonar.server.ws.WsParameterBuilder.createRootQualifierParameter;
 import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
@@ -59,17 +73,17 @@ public class SearchProjectPermissionsAction implements PermissionsWsAction {
   private final UserSession userSession;
   private final I18n i18n;
   private final ResourceTypes resourceTypes;
-  private final SearchProjectPermissionsDataLoader dataLoader;
   private final PermissionWsSupport wsSupport;
+  private final String[] rootQualifiers;
 
   public SearchProjectPermissionsAction(DbClient dbClient, UserSession userSession, I18n i18n, ResourceTypes resourceTypes,
-    SearchProjectPermissionsDataLoader dataLoader, PermissionWsSupport wsSupport) {
+    PermissionWsSupport wsSupport) {
     this.dbClient = dbClient;
     this.userSession = userSession;
     this.i18n = i18n;
     this.resourceTypes = resourceTypes;
-    this.dataLoader = dataLoader;
     this.wsSupport = wsSupport;
+    this.rootQualifiers = Collections2.transform(resourceTypes.getRoots(), ResourceType::getQualifier).toArray(new String[resourceTypes.getRoots().size()]);
   }
 
   @Override
@@ -108,7 +122,7 @@ public class SearchProjectPermissionsAction implements PermissionsWsAction {
     try (DbSession dbSession = dbClient.openSession(false)) {
       checkAuthorized(dbSession, request);
       validateQualifier(request.getQualifier(), resourceTypes);
-      SearchProjectPermissionsData data = dataLoader.load(dbSession, request);
+      SearchProjectPermissionsData data = load(dbSession, request);
       return buildResponse(data);
     }
   }
@@ -182,4 +196,140 @@ public class SearchProjectPermissionsAction implements PermissionsWsAction {
   private String i18nName(String permissionKey) {
     return i18n.message(Locale.ENGLISH, PROPERTY_PREFIX + permissionKey, permissionKey);
   }
+
+  private SearchProjectPermissionsData load(DbSession dbSession, SearchProjectPermissionsRequest request) {
+    SearchProjectPermissionsData.Builder data = newBuilder();
+    int countRootComponents = countRootComponents(dbSession, request);
+    List<ComponentDto> rootComponents = searchRootComponents(dbSession, request, paging(request, countRootComponents));
+    List<Long> rootComponentIds = Lists.transform(rootComponents, ComponentDto::getId);
+
+    data.rootComponents(rootComponents)
+            .paging(paging(request, countRootComponents))
+            .userCountByProjectIdAndPermission(userCountByRootComponentIdAndPermission(dbSession, rootComponentIds))
+            .groupCountByProjectIdAndPermission(groupCountByRootComponentIdAndPermission(dbSession, rootComponentIds));
+
+    return data.build();
+  }
+
+  private static Paging paging(SearchProjectPermissionsRequest request, int total) {
+    return forPageIndex(request.getPage())
+            .withPageSize(request.getPageSize())
+            .andTotal(total);
+  }
+
+  private int countRootComponents(DbSession dbSession, SearchProjectPermissionsRequest request) {
+    return dbClient.componentDao().countByQuery(dbSession, toDbQuery(request));
+  }
+
+  private List<ComponentDto> searchRootComponents(DbSession dbSession, SearchProjectPermissionsRequest request, Paging paging) {
+    com.google.common.base.Optional<ProjectWsRef> project = newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey());
+
+    if (project.isPresent()) {
+      return singletonList(wsSupport.getRootComponentOrModule(dbSession, project.get()));
+    }
+
+    return dbClient.componentDao().selectByQuery(dbSession, toDbQuery(request), paging.offset(), paging.pageSize());
+  }
+
+  private ComponentQuery toDbQuery(SearchProjectPermissionsRequest wsRequest) {
+    return ComponentQuery.builder()
+            .setQualifiers(qualifiers(wsRequest.getQualifier()))
+            .setNameOrKeyQuery(wsRequest.getQuery())
+            .build();
+  }
+
+  private String[] qualifiers(@Nullable String requestQualifier) {
+    return requestQualifier == null
+            ? rootQualifiers
+            : (new String[] {requestQualifier});
+  }
+
+  private Table<Long, String, Integer> userCountByRootComponentIdAndPermission(DbSession dbSession, List<Long> rootComponentIds) {
+    final Table<Long, String, Integer> userCountByRootComponentIdAndPermission = TreeBasedTable.create();
+
+    dbClient.userPermissionDao().countUsersByProjectPermission(dbSession, rootComponentIds).forEach(
+            row -> userCountByRootComponentIdAndPermission.put(row.getComponentId(), row.getPermission(), row.getCount()));
+
+    return userCountByRootComponentIdAndPermission;
+  }
+
+  private Table<Long, String, Integer> groupCountByRootComponentIdAndPermission(DbSession dbSession, List<Long> rootComponentIds) {
+    final Table<Long, String, Integer> userCountByRootComponentIdAndPermission = TreeBasedTable.create();
+
+    dbClient.groupPermissionDao().groupsCountByComponentIdAndPermission(dbSession, rootComponentIds, context -> {
+      CountPerProjectPermission row = (CountPerProjectPermission) context.getResultObject();
+      userCountByRootComponentIdAndPermission.put(row.getComponentId(), row.getPermission(), row.getCount());
+    });
+
+    return userCountByRootComponentIdAndPermission;
+  }
+
+  private static class SearchProjectPermissionsRequest {
+    private String projectId;
+    private String projectKey;
+    private String qualifier;
+    private Integer page;
+    private Integer pageSize;
+    private String query;
+
+    @CheckForNull
+    public String getProjectId() {
+      return projectId;
+    }
+
+    public SearchProjectPermissionsRequest setProjectId(@Nullable String projectId) {
+      this.projectId = projectId;
+      return this;
+    }
+
+    @CheckForNull
+    public String getProjectKey() {
+      return projectKey;
+    }
+
+    public SearchProjectPermissionsRequest setProjectKey(@Nullable String projectKey) {
+      this.projectKey = projectKey;
+      return this;
+    }
+
+    @CheckForNull
+    public Integer getPage() {
+      return page;
+    }
+
+    public SearchProjectPermissionsRequest setPage(int page) {
+      this.page = page;
+      return this;
+    }
+
+    @CheckForNull
+    public Integer getPageSize() {
+      return pageSize;
+    }
+
+    public SearchProjectPermissionsRequest setPageSize(int pageSize) {
+      this.pageSize = pageSize;
+      return this;
+    }
+
+    @CheckForNull
+    public String getQuery() {
+      return query;
+    }
+
+    public SearchProjectPermissionsRequest setQuery(@Nullable String query) {
+      this.query = query;
+      return this;
+    }
+
+    @CheckForNull
+    public String getQualifier() {
+      return qualifier;
+    }
+
+    public SearchProjectPermissionsRequest setQualifier(@Nullable String qualifier) {
+      this.qualifier = qualifier;
+      return this;
+    }
+  }
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsDataLoader.java
deleted file mode 100644 (file)
index 973144f..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.permission.ws;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Table;
-import com.google.common.collect.TreeBasedTable;
-import java.util.List;
-import javax.annotation.Nullable;
-import org.sonar.api.resources.ResourceType;
-import org.sonar.api.resources.ResourceTypes;
-import org.sonar.api.utils.Paging;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentQuery;
-import org.sonar.db.permission.CountPerProjectPermission;
-import org.sonarqube.ws.client.permission.SearchProjectPermissionsRequest;
-
-import static java.util.Collections.singletonList;
-import static org.sonar.api.utils.Paging.forPageIndex;
-import static org.sonar.server.permission.ws.ProjectWsRef.newOptionalWsProjectRef;
-import static org.sonar.server.permission.ws.SearchProjectPermissionsData.newBuilder;
-
-public class SearchProjectPermissionsDataLoader {
-  private final DbClient dbClient;
-  private final PermissionWsSupport wsSupport;
-  private final String[] rootQualifiers;
-
-  public SearchProjectPermissionsDataLoader(DbClient dbClient, PermissionWsSupport wsSupport, ResourceTypes resourceTypes) {
-    this.dbClient = dbClient;
-    this.wsSupport = wsSupport;
-    this.rootQualifiers = Collections2.transform(resourceTypes.getRoots(), ResourceType::getQualifier).toArray(new String[resourceTypes.getRoots().size()]);
-  }
-
-  SearchProjectPermissionsData load(DbSession dbSession, SearchProjectPermissionsRequest request) {
-    SearchProjectPermissionsData.Builder data = newBuilder();
-    int countRootComponents = countRootComponents(dbSession, request);
-    List<ComponentDto> rootComponents = searchRootComponents(dbSession, request, paging(request, countRootComponents));
-    List<Long> rootComponentIds = Lists.transform(rootComponents, ComponentDto::getId);
-
-    data.rootComponents(rootComponents)
-      .paging(paging(request, countRootComponents))
-      .userCountByProjectIdAndPermission(userCountByRootComponentIdAndPermission(dbSession, rootComponentIds))
-      .groupCountByProjectIdAndPermission(groupCountByRootComponentIdAndPermission(dbSession, rootComponentIds));
-
-    return data.build();
-  }
-
-  private static Paging paging(SearchProjectPermissionsRequest request, int total) {
-    return forPageIndex(request.getPage())
-      .withPageSize(request.getPageSize())
-      .andTotal(total);
-  }
-
-  private int countRootComponents(DbSession dbSession, SearchProjectPermissionsRequest request) {
-    return dbClient.componentDao().countByQuery(dbSession, toDbQuery(request));
-  }
-
-  private List<ComponentDto> searchRootComponents(DbSession dbSession, SearchProjectPermissionsRequest request, Paging paging) {
-    Optional<ProjectWsRef> project = newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey());
-
-    if (project.isPresent()) {
-      return singletonList(wsSupport.getRootComponentOrModule(dbSession, project.get()));
-    }
-
-    return dbClient.componentDao().selectByQuery(dbSession, toDbQuery(request), paging.offset(), paging.pageSize());
-  }
-
-  private ComponentQuery toDbQuery(SearchProjectPermissionsRequest wsRequest) {
-    return ComponentQuery.builder()
-      .setQualifiers(qualifiers(wsRequest.getQualifier()))
-      .setNameOrKeyQuery(wsRequest.getQuery())
-      .build();
-  }
-
-  private String[] qualifiers(@Nullable String requestQualifier) {
-    return requestQualifier == null
-      ? rootQualifiers
-      : (new String[] {requestQualifier});
-  }
-
-  private Table<Long, String, Integer> userCountByRootComponentIdAndPermission(DbSession dbSession, List<Long> rootComponentIds) {
-    final Table<Long, String, Integer> userCountByRootComponentIdAndPermission = TreeBasedTable.create();
-
-    dbClient.userPermissionDao().countUsersByProjectPermission(dbSession, rootComponentIds).forEach(
-      row -> userCountByRootComponentIdAndPermission.put(row.getComponentId(), row.getPermission(), row.getCount()));
-
-    return userCountByRootComponentIdAndPermission;
-  }
-
-  private Table<Long, String, Integer> groupCountByRootComponentIdAndPermission(DbSession dbSession, List<Long> rootComponentIds) {
-    final Table<Long, String, Integer> userCountByRootComponentIdAndPermission = TreeBasedTable.create();
-
-    dbClient.groupPermissionDao().groupsCountByComponentIdAndPermission(dbSession, rootComponentIds, context -> {
-      CountPerProjectPermission row = (CountPerProjectPermission) context.getResultObject();
-      userCountByRootComponentIdAndPermission.put(row.getComponentId(), row.getPermission(), row.getCount());
-    });
-
-    return userCountByRootComponentIdAndPermission;
-  }
-}
index 0d4956088e2947187247cf6dbde6bf09107684de..2c8d5e1705ca4998370f6f2fb2f8c9d3f377ece3 100644 (file)
@@ -31,8 +31,11 @@ import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.server.permission.ws.PermissionWsSupport;
 import org.sonar.server.permission.ws.PermissionsWsAction;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.permission.AddProjectCreatorToTemplateRequest;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import static java.util.Objects.requireNonNull;
 import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin;
 import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission;
 import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectPermissionParameter;
@@ -119,4 +122,76 @@ public class AddProjectCreatorToTemplateAction implements PermissionsWsAction {
     dbClient.permissionTemplateCharacteristicDao().update(dbSession, targetTemplatePermission);
     dbSession.commit();
   }
+
+  private static class AddProjectCreatorToTemplateRequest {
+    private final String templateId;
+    private final String organization;
+    private final String templateName;
+    private final String permission;
+
+    private AddProjectCreatorToTemplateRequest(Builder builder) {
+      this.templateId = builder.templateId;
+      this.organization = builder.organization;
+      this.templateName = builder.templateName;
+      this.permission = requireNonNull(builder.permission);
+    }
+
+    @CheckForNull
+    public String getTemplateId() {
+      return templateId;
+    }
+
+    @CheckForNull
+    public String getOrganization() {
+      return organization;
+    }
+
+    @CheckForNull
+    public String getTemplateName() {
+      return templateName;
+    }
+
+    public String getPermission() {
+      return permission;
+    }
+
+    public static Builder builder() {
+      return new Builder();
+    }
+  }
+
+  private static class Builder {
+    private String templateId;
+    private String organization;
+    private String templateName;
+    private String permission;
+
+    private Builder() {
+      // enforce method constructor
+    }
+
+    public Builder setTemplateId(@Nullable String templateId) {
+      this.templateId = templateId;
+      return this;
+    }
+
+    public Builder setOrganization(@Nullable String s) {
+      this.organization = s;
+      return this;
+    }
+
+    public Builder setTemplateName(@Nullable String templateName) {
+      this.templateName = templateName;
+      return this;
+    }
+
+    public Builder setPermission(@Nullable String permission) {
+      this.permission = permission;
+      return this;
+    }
+
+    public AddProjectCreatorToTemplateRequest build() {
+      return new AddProjectCreatorToTemplateRequest(this);
+    }
+  }
 }
index 5c38b5a5ab76d6d55126a6180ae1a1909ed305b8..d40e26891f1a280d308f460fa59b88949b533ab6 100644 (file)
@@ -32,8 +32,11 @@ import org.sonar.server.permission.UserId;
 import org.sonar.server.permission.ws.PermissionWsSupport;
 import org.sonar.server.permission.ws.PermissionsWsAction;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.permission.AddUserToTemplateRequest;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import static java.util.Objects.requireNonNull;
 import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin;
 import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectPermissionParameter;
 import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createTemplateParameters;
@@ -110,4 +113,60 @@ public class AddUserToTemplateAction implements PermissionsWsAction {
     List<String> usersWithPermission = dbClient.permissionTemplateDao().selectUserLoginsByQueryAndTemplate(dbSession, permissionQuery, templateId);
     return usersWithPermission.stream().anyMatch(s -> s.equals(userLogin));
   }
+
+  private static class AddUserToTemplateRequest {
+    private String login;
+    private String permission;
+    private String templateId;
+    private String organization;
+    private String templateName;
+
+    public String getLogin() {
+      return login;
+    }
+
+    public AddUserToTemplateRequest setLogin(String login) {
+      this.login = requireNonNull(login);
+      return this;
+    }
+
+    public String getPermission() {
+      return permission;
+    }
+
+    public AddUserToTemplateRequest setPermission(String permission) {
+      this.permission = requireNonNull(permission);
+      return this;
+    }
+
+    @CheckForNull
+    public String getTemplateId() {
+      return templateId;
+    }
+
+    public AddUserToTemplateRequest setTemplateId(@Nullable String templateId) {
+      this.templateId = templateId;
+      return this;
+    }
+
+    @CheckForNull
+    public String getTemplateName() {
+      return templateName;
+    }
+
+    public AddUserToTemplateRequest setTemplateName(@Nullable String templateName) {
+      this.templateName = templateName;
+      return this;
+    }
+
+    @CheckForNull
+    public String getOrganization() {
+      return organization;
+    }
+
+    public AddUserToTemplateRequest setOrganization(@Nullable String s) {
+      this.organization = s;
+      return this;
+    }
+  }
 }
index 655d3a866f545aa1dd6415eecdebd4c865db630c..7997867e9e735ecc5a1feb3d91cd0506e5f7a68c 100644 (file)
@@ -31,7 +31,9 @@ import org.sonar.server.permission.PermissionTemplateService;
 import org.sonar.server.permission.ws.PermissionWsSupport;
 import org.sonar.server.permission.ws.PermissionsWsAction;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.permission.ApplyTemplateRequest;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 
 import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin;
 import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters;
@@ -99,4 +101,61 @@ public class ApplyTemplateAction implements PermissionsWsAction {
       permissionTemplateService.applyAndCommit(dbSession, template, Collections.singletonList(project));
     }
   }
+
+  private static class ApplyTemplateRequest {
+    private String projectId;
+    private String projectKey;
+    private String templateId;
+    private String organization;
+    private String templateName;
+
+    @CheckForNull
+    public String getProjectId() {
+      return projectId;
+    }
+
+    public ApplyTemplateRequest setProjectId(@Nullable String projectId) {
+      this.projectId = projectId;
+      return this;
+    }
+
+    @CheckForNull
+    public String getProjectKey() {
+      return projectKey;
+    }
+
+    public ApplyTemplateRequest setProjectKey(@Nullable String projectKey) {
+      this.projectKey = projectKey;
+      return this;
+    }
+
+    @CheckForNull
+    public String getTemplateId() {
+      return templateId;
+    }
+
+    public ApplyTemplateRequest setTemplateId(@Nullable String templateId) {
+      this.templateId = templateId;
+      return this;
+    }
+
+    @CheckForNull
+    public String getOrganization() {
+      return organization;
+    }
+
+    public ApplyTemplateRequest setOrganization(@Nullable String s) {
+      this.organization = s;
+      return this;
+    }
+    @CheckForNull
+    public String getTemplateName() {
+      return templateName;
+    }
+
+    public ApplyTemplateRequest setTemplateName(@Nullable String templateName) {
+      this.templateName = templateName;
+      return this;
+    }
+  }
 }
index e2f82dfc576d202bd32aa528e989152e7cd644b9..413fed5ead1489e245c46c48e45f81323e1f8e18 100644 (file)
@@ -39,8 +39,12 @@ import org.sonar.server.permission.ws.PermissionWsSupport;
 import org.sonar.server.permission.ws.PermissionsWsAction;
 import org.sonar.server.project.Visibility;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.permission.BulkApplyTemplateRequest;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import static java.util.Collections.singleton;
+import static java.util.Objects.requireNonNull;
 import static org.sonar.api.utils.DateUtils.parseDateOrDateTime;
 import static org.sonar.core.util.Protobuf.setNullable;
 import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin;
@@ -181,4 +185,103 @@ public class BulkApplyTemplateAction implements PermissionsWsAction {
     return query.build();
   }
 
+  private static class BulkApplyTemplateRequest {
+    private String templateId;
+    private String organization;
+    private String templateName;
+    private String query;
+    private Collection<String> qualifiers = singleton(Qualifiers.PROJECT);
+    private String visibility;
+    private String analyzedBefore;
+    private boolean onProvisionedOnly = false;
+    private Collection<String> projects;
+
+    @CheckForNull
+    public String getTemplateId() {
+      return templateId;
+    }
+
+    public BulkApplyTemplateRequest setTemplateId(@Nullable String templateId) {
+      this.templateId = templateId;
+      return this;
+    }
+
+    @CheckForNull
+    public String getOrganization() {
+      return organization;
+    }
+
+    public BulkApplyTemplateRequest setOrganization(@Nullable String s) {
+      this.organization = s;
+      return this;
+    }
+
+    @CheckForNull
+    public String getTemplateName() {
+      return templateName;
+    }
+
+    public BulkApplyTemplateRequest setTemplateName(@Nullable String templateName) {
+      this.templateName = templateName;
+      return this;
+    }
+
+    @CheckForNull
+    public String getQuery() {
+      return query;
+    }
+
+    public BulkApplyTemplateRequest setQuery(@Nullable String query) {
+      this.query = query;
+      return this;
+    }
+
+    public Collection<String> getQualifiers() {
+      return qualifiers;
+    }
+
+    public BulkApplyTemplateRequest setQualifiers(Collection<String> qualifiers) {
+      this.qualifiers = requireNonNull(qualifiers);
+      return this;
+    }
+
+    @CheckForNull
+    public String getVisibility() {
+      return visibility;
+    }
+
+    public BulkApplyTemplateRequest setVisibility(@Nullable String visibility) {
+      this.visibility = visibility;
+      return this;
+    }
+
+    @CheckForNull
+    public String getAnalyzedBefore() {
+      return analyzedBefore;
+    }
+
+    public BulkApplyTemplateRequest setAnalyzedBefore(@Nullable String analyzedBefore) {
+      this.analyzedBefore = analyzedBefore;
+      return this;
+    }
+
+    public boolean isOnProvisionedOnly() {
+      return onProvisionedOnly;
+    }
+
+    public BulkApplyTemplateRequest setOnProvisionedOnly(boolean onProvisionedOnly) {
+      this.onProvisionedOnly = onProvisionedOnly;
+      return this;
+    }
+
+    @CheckForNull
+    public Collection<String> getProjects() {
+      return projects;
+    }
+
+    public BulkApplyTemplateRequest setProjects(@Nullable Collection<String> projects) {
+      this.projects = projects;
+      return this;
+    }
+  }
 }
index 216cec4e230bd67528321c33bda1781d44afe622..0e6f0f7015355152fe3ae7b2b7e952067f2788e5 100644 (file)
@@ -34,9 +34,12 @@ import org.sonar.server.permission.ws.PermissionsWsAction;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Permissions.CreateTemplateWsResponse;
 import org.sonarqube.ws.Permissions.PermissionTemplate;
-import org.sonarqube.ws.client.permission.CreateTemplateRequest;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 
 import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
 import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin;
 import static org.sonar.server.permission.ws.PermissionRequestValidator.MSG_TEMPLATE_WITH_SAME_NAME;
 import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPattern;
@@ -139,4 +142,50 @@ public class CreateTemplateAction implements PermissionsWsAction {
     dbSession.commit();
     return template;
   }
+
+  private static class CreateTemplateRequest {
+    private String description;
+    private String name;
+    private String projectKeyPattern;
+    private String organization;
+
+    @CheckForNull
+    public String getDescription() {
+      return description;
+    }
+
+    public CreateTemplateRequest setDescription(@Nullable String description) {
+      this.description = description;
+      return this;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    public CreateTemplateRequest setName(String name) {
+      this.name = requireNonNull(name);
+      return this;
+    }
+
+    @CheckForNull
+    public String getProjectKeyPattern() {
+      return projectKeyPattern;
+    }
+
+    public CreateTemplateRequest setProjectKeyPattern(@Nullable String projectKeyPattern) {
+      this.projectKeyPattern = projectKeyPattern;
+      return this;
+    }
+
+    @CheckForNull
+    public String getOrganization() {
+      return organization;
+    }
+
+    public CreateTemplateRequest setOrganization(@Nullable String s) {
+      this.organization = s;
+      return this;
+    }
+  }
 }
index 821364c7fe01df81a735273ffcbd53a0e6e082b2..ddcc6a46db4bf5a7b6b49ed59dc0f74e07c86b61 100644 (file)
@@ -29,7 +29,9 @@ import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.server.permission.ws.PermissionWsSupport;
 import org.sonar.server.permission.ws.PermissionsWsAction;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.permission.DeleteTemplateRequest;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 
 import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin;
 import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createTemplateParameters;
@@ -124,4 +126,39 @@ public class DeleteTemplateAction implements PermissionsWsAction {
         "It is not possible to delete the default permission template for views"));
   }
 
+  private static class DeleteTemplateRequest {
+    private String templateId;
+    private String organization;
+    private String templateName;
+
+    @CheckForNull
+    public String getTemplateId() {
+      return templateId;
+    }
+
+    public DeleteTemplateRequest setTemplateId(@Nullable String templateId) {
+      this.templateId = templateId;
+      return this;
+    }
+
+    @CheckForNull
+    public String getOrganization() {
+      return organization;
+    }
+
+    public DeleteTemplateRequest setOrganization(@Nullable String s) {
+      this.organization = s;
+      return this;
+    }
+
+    @CheckForNull
+    public String getTemplateName() {
+      return templateName;
+    }
+
+    public DeleteTemplateRequest setTemplateName(@Nullable String templateName) {
+      this.templateName = templateName;
+      return this;
+    }
+  }
 }
index 2ff3728cb0b5556aa8f83760ce4cee4e0f46f0a2..111b14d69c92acf518cbd909de9fa0ab9907279a 100644 (file)
@@ -31,8 +31,11 @@ import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.server.permission.ws.PermissionWsSupport;
 import org.sonar.server.permission.ws.PermissionsWsAction;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.permission.RemoveProjectCreatorFromTemplateRequest;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import static java.util.Objects.requireNonNull;
 import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin;
 import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission;
 import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectPermissionParameter;
@@ -104,4 +107,76 @@ public class RemoveProjectCreatorFromTemplateAction implements PermissionsWsActi
     dbClient.permissionTemplateCharacteristicDao().update(dbSession, targetTemplatePermission);
     dbSession.commit();
   }
+
+  private static class RemoveProjectCreatorFromTemplateRequest {
+    private final String templateId;
+    private final String organization;
+    private final String templateName;
+    private final String permission;
+
+    private RemoveProjectCreatorFromTemplateRequest(Builder builder) {
+      this.templateId = builder.templateId;
+      this.organization = builder.organization;
+      this.templateName = builder.templateName;
+      this.permission = requireNonNull(builder.permission);
+    }
+
+    @CheckForNull
+    public String getTemplateId() {
+      return templateId;
+    }
+
+    @CheckForNull
+    public String getOrganization() {
+      return organization;
+    }
+
+    @CheckForNull
+    public String getTemplateName() {
+      return templateName;
+    }
+
+    public String getPermission() {
+      return permission;
+    }
+
+    public static Builder builder() {
+      return new Builder();
+    }
+  }
+
+  public static class Builder {
+    private String templateId;
+    private String organization;
+    private String templateName;
+    private String permission;
+
+    private Builder() {
+      // enforce method constructor
+    }
+
+    public Builder setTemplateId(@Nullable String templateId) {
+      this.templateId = templateId;
+      return this;
+    }
+
+    public Builder setOrganization(@Nullable String s) {
+      this.organization = s;
+      return this;
+    }
+
+    public Builder setTemplateName(@Nullable String templateName) {
+      this.templateName = templateName;
+      return this;
+    }
+
+    public Builder setPermission(@Nullable String permission) {
+      this.permission = permission;
+      return this;
+    }
+
+    public RemoveProjectCreatorFromTemplateRequest build() {
+      return new RemoveProjectCreatorFromTemplateRequest(this);
+    }
+  }
 }
index f91d243ae2ccca21fd361e71445a07ef3a976d06..75ad5a2d3e9cfcb2c88ed423925bded1e9231c96 100644 (file)
@@ -29,8 +29,11 @@ import org.sonar.server.permission.UserId;
 import org.sonar.server.permission.ws.PermissionWsSupport;
 import org.sonar.server.permission.ws.PermissionsWsAction;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.permission.RemoveUserFromTemplateRequest;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import static java.util.Objects.requireNonNull;
 import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin;
 import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission;
 import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectPermissionParameter;
@@ -99,4 +102,60 @@ public class RemoveUserFromTemplateAction implements PermissionsWsAction {
       dbSession.commit();
     }
   }
+
+  private static class RemoveUserFromTemplateRequest {
+    private String login;
+    private String permission;
+    private String templateId;
+    private String organization;
+    private String templateName;
+
+    public String getLogin() {
+      return login;
+    }
+
+    public RemoveUserFromTemplateRequest setLogin(String login) {
+      this.login = requireNonNull(login);
+      return this;
+    }
+
+    public String getPermission() {
+      return permission;
+    }
+
+    public RemoveUserFromTemplateRequest setPermission(String permission) {
+      this.permission = requireNonNull(permission);
+      return this;
+    }
+
+    @CheckForNull
+    public String getTemplateId() {
+      return templateId;
+    }
+
+    public RemoveUserFromTemplateRequest setTemplateId(@Nullable String templateId) {
+      this.templateId = templateId;
+      return this;
+    }
+
+    @CheckForNull
+    public String getOrganization() {
+      return organization;
+    }
+
+    public RemoveUserFromTemplateRequest setOrganization(@Nullable String s) {
+      this.organization = s;
+      return this;
+    }
+
+    @CheckForNull
+    public String getTemplateName() {
+      return templateName;
+    }
+
+    public RemoveUserFromTemplateRequest setTemplateName(@Nullable String templateName) {
+      this.templateName = templateName;
+      return this;
+    }
+  }
 }
index 29e68967dd0441ef3a6e03f816f2a5509602aa04..b7568c127e3e4ee4bcd89fb278c5be7c5c9d651d 100644 (file)
  */
 package org.sonar.server.permission.ws.template;
 
+import java.util.List;
 import java.util.Locale;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Table;
+import com.google.common.collect.TreeBasedTable;
 import org.sonar.api.i18n.I18n;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.server.ws.Request;
@@ -29,7 +34,10 @@ import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.core.permission.ProjectPermissions;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
+import org.sonar.db.organization.DefaultTemplates;
 import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.permission.template.CountByTemplateAndPermissionDto;
+import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto;
 import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.server.permission.ws.PermissionWsSupport;
 import org.sonar.server.permission.ws.PermissionsWsAction;
@@ -39,12 +47,16 @@ import org.sonarqube.ws.Permissions.Permission;
 import org.sonarqube.ws.Permissions.PermissionTemplate;
 import org.sonarqube.ws.Permissions.SearchTemplatesWsResponse;
 import org.sonarqube.ws.Permissions.SearchTemplatesWsResponse.TemplateIdQualifier;
-import org.sonarqube.ws.client.permission.SearchTemplatesRequest;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 
 import static org.sonar.api.utils.DateUtils.formatDateTime;
 import static org.sonar.core.util.Protobuf.setNullable;
 import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin;
 import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createOrganizationParameter;
+import static org.sonar.server.permission.ws.template.SearchTemplatesData.builder;
+import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION;
 
@@ -56,14 +68,14 @@ public class SearchTemplatesAction implements PermissionsWsAction {
   private final UserSession userSession;
   private final I18n i18n;
   private final PermissionWsSupport support;
-  private final SearchTemplatesDataLoader dataLoader;
+  private final DefaultTemplatesResolver defaultTemplatesResolver;
 
-  public SearchTemplatesAction(DbClient dbClient, UserSession userSession, I18n i18n, PermissionWsSupport support, SearchTemplatesDataLoader dataLoader) {
+  public SearchTemplatesAction(DbClient dbClient, UserSession userSession, I18n i18n, PermissionWsSupport support, DefaultTemplatesResolver defaultTemplatesResolver) {
     this.dbClient = dbClient;
     this.userSession = userSession;
     this.i18n = i18n;
     this.support = support;
-    this.dataLoader = dataLoader;
+    this.defaultTemplatesResolver = defaultTemplatesResolver;
   }
 
   @Override
@@ -88,7 +100,7 @@ public class SearchTemplatesAction implements PermissionsWsAction {
         .setQuery(wsRequest.param(Param.TEXT_QUERY));
       checkGlobalAdmin(userSession, request.getOrganizationUuid());
 
-      SearchTemplatesWsResponse searchTemplatesWsResponse = buildResponse(dataLoader.load(dbSession, request));
+      SearchTemplatesWsResponse searchTemplatesWsResponse = buildResponse(load(dbSession, request));
       writeProtobuf(searchTemplatesWsResponse, wsRequest, wsResponse);
     }
   }
@@ -164,4 +176,84 @@ public class SearchTemplatesAction implements PermissionsWsAction {
   private String i18nName(String permissionKey) {
     return i18n.message(Locale.ENGLISH, PROPERTY_PREFIX + permissionKey, permissionKey);
   }
+
+  private SearchTemplatesData load(DbSession dbSession, SearchTemplatesRequest request) {
+    SearchTemplatesData.Builder data = builder();
+    List<PermissionTemplateDto> templates = searchTemplates(dbSession, request);
+    List<Long> templateIds = Lists.transform(templates, PermissionTemplateDto::getId);
+
+    DefaultTemplates defaultTemplates = checkFoundWithOptional(
+            dbClient.organizationDao().getDefaultTemplates(dbSession, request.getOrganizationUuid()),
+            "No Default templates for organization with uuid '%s'", request.getOrganizationUuid());
+    DefaultTemplatesResolver.ResolvedDefaultTemplates resolvedDefaultTemplates = defaultTemplatesResolver.resolve(defaultTemplates);
+
+    data.templates(templates)
+            .defaultTemplates(resolvedDefaultTemplates)
+            .userCountByTemplateIdAndPermission(userCountByTemplateIdAndPermission(dbSession, templateIds))
+            .groupCountByTemplateIdAndPermission(groupCountByTemplateIdAndPermission(dbSession, templateIds))
+            .withProjectCreatorByTemplateIdAndPermission(withProjectCreatorsByTemplateIdAndPermission(dbSession, templateIds));
+
+    return data.build();
+  }
+
+  private List<PermissionTemplateDto> searchTemplates(DbSession dbSession, SearchTemplatesRequest request) {
+    return dbClient.permissionTemplateDao().selectAll(dbSession, request.getOrganizationUuid(), request.getQuery());
+  }
+
+  private Table<Long, String, Integer> userCountByTemplateIdAndPermission(DbSession dbSession, List<Long> templateIds) {
+    final Table<Long, String, Integer> userCountByTemplateIdAndPermission = TreeBasedTable.create();
+
+    dbClient.permissionTemplateDao().usersCountByTemplateIdAndPermission(dbSession, templateIds, context -> {
+      CountByTemplateAndPermissionDto row = context.getResultObject();
+      userCountByTemplateIdAndPermission.put(row.getTemplateId(), row.getPermission(), row.getCount());
+    });
+
+    return userCountByTemplateIdAndPermission;
+  }
+
+  private Table<Long, String, Integer> groupCountByTemplateIdAndPermission(DbSession dbSession, List<Long> templateIds) {
+    final Table<Long, String, Integer> userCountByTemplateIdAndPermission = TreeBasedTable.create();
+
+    dbClient.permissionTemplateDao().groupsCountByTemplateIdAndPermission(dbSession, templateIds, context -> {
+      CountByTemplateAndPermissionDto row = context.getResultObject();
+      userCountByTemplateIdAndPermission.put(row.getTemplateId(), row.getPermission(), row.getCount());
+    });
+
+    return userCountByTemplateIdAndPermission;
+  }
+
+  private Table<Long, String, Boolean> withProjectCreatorsByTemplateIdAndPermission(DbSession dbSession, List<Long> templateIds) {
+    final Table<Long, String, Boolean> templatePermissionsByTemplateIdAndPermission = TreeBasedTable.create();
+
+    List<PermissionTemplateCharacteristicDto> templatePermissions = dbClient.permissionTemplateCharacteristicDao().selectByTemplateIds(dbSession, templateIds);
+    templatePermissions.stream()
+            .forEach(templatePermission -> templatePermissionsByTemplateIdAndPermission.put(templatePermission.getTemplateId(), templatePermission.getPermission(),
+                    templatePermission.getWithProjectCreator()));
+
+    return templatePermissionsByTemplateIdAndPermission;
+  }
+
+  private static class SearchTemplatesRequest {
+    private String query;
+    private String organizationUuid;
+
+    @CheckForNull
+    public String getQuery() {
+      return query;
+    }
+
+    public SearchTemplatesRequest setQuery(@Nullable String query) {
+      this.query = query;
+      return this;
+    }
+
+    public String getOrganizationUuid() {
+      return organizationUuid;
+    }
+
+    public SearchTemplatesRequest setOrganizationUuid(String s) {
+      this.organizationUuid = s;
+      return this;
+    }
+  }
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesDataLoader.java
deleted file mode 100644 (file)
index c95aa7f..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.permission.ws.template;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Table;
-import com.google.common.collect.TreeBasedTable;
-import java.util.List;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.organization.DefaultTemplates;
-import org.sonar.db.permission.template.CountByTemplateAndPermissionDto;
-import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto;
-import org.sonar.db.permission.template.PermissionTemplateDto;
-import org.sonar.server.permission.ws.template.DefaultTemplatesResolver.ResolvedDefaultTemplates;
-import org.sonarqube.ws.client.permission.SearchTemplatesRequest;
-
-import static org.sonar.server.permission.ws.template.SearchTemplatesData.builder;
-import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
-
-public class SearchTemplatesDataLoader {
-  private final DbClient dbClient;
-  private final DefaultTemplatesResolver defaultTemplatesResolver;
-
-  public SearchTemplatesDataLoader(DbClient dbClient, DefaultTemplatesResolver defaultTemplatesResolver) {
-    this.dbClient = dbClient;
-    this.defaultTemplatesResolver = defaultTemplatesResolver;
-  }
-
-  public SearchTemplatesData load(DbSession dbSession, SearchTemplatesRequest request) {
-    SearchTemplatesData.Builder data = builder();
-    List<PermissionTemplateDto> templates = searchTemplates(dbSession, request);
-    List<Long> templateIds = Lists.transform(templates, PermissionTemplateDto::getId);
-
-    DefaultTemplates defaultTemplates = checkFoundWithOptional(
-        dbClient.organizationDao().getDefaultTemplates(dbSession, request.getOrganizationUuid()),
-        "No Default templates for organization with uuid '%s'", request.getOrganizationUuid());
-    ResolvedDefaultTemplates resolvedDefaultTemplates = defaultTemplatesResolver.resolve(defaultTemplates);
-
-    data.templates(templates)
-      .defaultTemplates(resolvedDefaultTemplates)
-      .userCountByTemplateIdAndPermission(userCountByTemplateIdAndPermission(dbSession, templateIds))
-      .groupCountByTemplateIdAndPermission(groupCountByTemplateIdAndPermission(dbSession, templateIds))
-      .withProjectCreatorByTemplateIdAndPermission(withProjectCreatorsByTemplateIdAndPermission(dbSession, templateIds));
-
-    return data.build();
-  }
-
-  private List<PermissionTemplateDto> searchTemplates(DbSession dbSession, SearchTemplatesRequest request) {
-    return dbClient.permissionTemplateDao().selectAll(dbSession, request.getOrganizationUuid(), request.getQuery());
-  }
-
-  private Table<Long, String, Integer> userCountByTemplateIdAndPermission(DbSession dbSession, List<Long> templateIds) {
-    final Table<Long, String, Integer> userCountByTemplateIdAndPermission = TreeBasedTable.create();
-
-    dbClient.permissionTemplateDao().usersCountByTemplateIdAndPermission(dbSession, templateIds, context -> {
-      CountByTemplateAndPermissionDto row = context.getResultObject();
-      userCountByTemplateIdAndPermission.put(row.getTemplateId(), row.getPermission(), row.getCount());
-    });
-
-    return userCountByTemplateIdAndPermission;
-  }
-
-  private Table<Long, String, Integer> groupCountByTemplateIdAndPermission(DbSession dbSession, List<Long> templateIds) {
-    final Table<Long, String, Integer> userCountByTemplateIdAndPermission = TreeBasedTable.create();
-
-    dbClient.permissionTemplateDao().groupsCountByTemplateIdAndPermission(dbSession, templateIds, context -> {
-      CountByTemplateAndPermissionDto row = context.getResultObject();
-      userCountByTemplateIdAndPermission.put(row.getTemplateId(), row.getPermission(), row.getCount());
-    });
-
-    return userCountByTemplateIdAndPermission;
-  }
-
-  private Table<Long, String, Boolean> withProjectCreatorsByTemplateIdAndPermission(DbSession dbSession, List<Long> templateIds) {
-    final Table<Long, String, Boolean> templatePermissionsByTemplateIdAndPermission = TreeBasedTable.create();
-
-    List<PermissionTemplateCharacteristicDto> templatePermissions = dbClient.permissionTemplateCharacteristicDao().selectByTemplateIds(dbSession, templateIds);
-    templatePermissions.stream()
-      .forEach(templatePermission -> templatePermissionsByTemplateIdAndPermission.put(templatePermission.getTemplateId(), templatePermission.getPermission(),
-        templatePermission.getWithProjectCreator()));
-
-    return templatePermissionsByTemplateIdAndPermission;
-  }
-}
index ea9ed0b4e71c92518ee060096ace21080ef4f813..e2c4fe436b39e72f85e00a3b36632aca73a31a6c 100644 (file)
@@ -33,7 +33,9 @@ import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.server.permission.ws.PermissionWsSupport;
 import org.sonar.server.permission.ws.PermissionsWsAction;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.permission.SetDefaultTemplateRequest;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 
 import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin;
 import static org.sonar.server.permission.ws.PermissionRequestValidator.validateQualifier;
@@ -121,4 +123,51 @@ public class SetDefaultTemplateAction implements PermissionsWsAction {
     }
     organizationDao.setDefaultTemplates(dbSession, organizationUuid, defaultTemplates);
   }
+
+  private static class SetDefaultTemplateRequest {
+    private String qualifier;
+    private String templateId;
+    private String organization;
+    private String templateName;
+
+    @CheckForNull
+    public String getQualifier() {
+      return qualifier;
+    }
+
+    public SetDefaultTemplateRequest setQualifier(@Nullable String qualifier) {
+      this.qualifier = qualifier;
+      return this;
+    }
+
+    @CheckForNull
+    public String getTemplateId() {
+      return templateId;
+    }
+
+    public SetDefaultTemplateRequest setTemplateId(@Nullable String templateId) {
+      this.templateId = templateId;
+      return this;
+    }
+
+    @CheckForNull
+    public String getOrganization() {
+      return organization;
+    }
+
+    public SetDefaultTemplateRequest setOrganization(@Nullable String s) {
+      this.organization = s;
+      return this;
+    }
+
+    @CheckForNull
+    public String getTemplateName() {
+      return templateName;
+    }
+
+    public SetDefaultTemplateRequest setTemplateName(@Nullable String templateName) {
+      this.templateName = templateName;
+      return this;
+    }
+  }
 }
index 94f59901b1ec094319b613870e1fb672599c05da..d81067fa1769c65478fe10038cff0e847c7cc6ae 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.server.permission.ws.template;
 
 import java.util.Date;
+import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
@@ -33,10 +34,10 @@ import org.sonar.server.permission.ws.PermissionsWsAction;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Permissions.PermissionTemplate;
 import org.sonarqube.ws.Permissions.UpdateTemplateWsResponse;
-import org.sonarqube.ws.client.permission.UpdateTemplateRequest;
 
 import static com.google.common.base.MoreObjects.firstNonNull;
 import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
 import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin;
 import static org.sonar.server.permission.ws.PermissionRequestValidator.MSG_TEMPLATE_WITH_SAME_NAME;
 import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPattern;
@@ -149,4 +150,50 @@ public class UpdateTemplateAction implements PermissionsWsAction {
     checkRequest(permissionTemplateWithSameName == null || permissionTemplateWithSameName.getId() == id,
       format(MSG_TEMPLATE_WITH_SAME_NAME, name));
   }
+
+  private static class UpdateTemplateRequest {
+    private String id;
+    private String description;
+    private String name;
+    private String projectKeyPattern;
+
+    public String getId() {
+      return id;
+    }
+
+    public UpdateTemplateRequest setId(String id) {
+      this.id = requireNonNull(id);
+      return this;
+    }
+
+    @CheckForNull
+    public String getDescription() {
+      return description;
+    }
+
+    public UpdateTemplateRequest setDescription(@Nullable String description) {
+      this.description = description;
+      return this;
+    }
+
+    @CheckForNull
+    public String getName() {
+      return name;
+    }
+
+    public UpdateTemplateRequest setName(@Nullable String name) {
+      this.name = name;
+      return this;
+    }
+
+    @CheckForNull
+    public String getProjectKeyPattern() {
+      return projectKeyPattern;
+    }
+
+    public UpdateTemplateRequest setProjectKeyPattern(@Nullable String projectKeyPattern) {
+      this.projectKeyPattern = projectKeyPattern;
+      return this;
+    }
+  }
 }
index a220e8761491d0c77a02ebc8c74cadc403ec01c1..151ef69393fe34bfdaffc4c8f6ce3ffff2080511 100644 (file)
@@ -31,7 +31,6 @@ import org.sonar.db.permission.OrganizationPermission;
 import org.sonar.server.component.ComponentCleanerService;
 import org.sonar.server.project.Visibility;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.project.SearchRequest;
 
 import static org.sonar.api.resources.Qualifiers.APP;
 import static org.sonar.api.resources.Qualifiers.PROJECT;
index d2a8cc844eb7970b34584324f0a127801d9c723b..5602de9845accafd4fe14b268dad5077b241d364 100644 (file)
@@ -36,8 +36,11 @@ import org.sonar.server.component.ComponentFinder.ParamNames;
 import org.sonar.server.component.ComponentService;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Projects.BulkUpdateKeyWsResponse;
-import org.sonarqube.ws.client.project.BulkUpdateKeyRequest;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import static com.google.common.base.Preconditions.checkArgument;
 import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
 import static org.sonar.db.component.ComponentKeyUpdaterDao.checkIsProjectOrModule;
 import static org.sonar.server.ws.WsUtils.checkRequest;
@@ -184,4 +187,89 @@ public class BulkUpdateKeyAction implements ProjectsWsAction {
       .setDryRun(request.mandatoryParamAsBoolean(PARAM_DRY_RUN))
       .build();
   }
+
+  private static class BulkUpdateKeyRequest {
+    private final String id;
+    private final String key;
+    private final String from;
+    private final String to;
+    private final boolean dryRun;
+
+    public BulkUpdateKeyRequest(Builder builder) {
+      this.id = builder.id;
+      this.key = builder.key;
+      this.from = builder.from;
+      this.to = builder.to;
+      this.dryRun = builder.dryRun;
+    }
+
+    @CheckForNull
+    public String getId() {
+      return id;
+    }
+
+    @CheckForNull
+    public String getKey() {
+      return key;
+    }
+
+    public String getFrom() {
+      return from;
+    }
+
+    public String getTo() {
+      return to;
+    }
+
+    public boolean isDryRun() {
+      return dryRun;
+    }
+
+    public static Builder builder() {
+      return new Builder();
+    }
+  }
+
+  public static class Builder {
+    private String id;
+    private String key;
+    private String from;
+    private String to;
+    private boolean dryRun;
+
+    private Builder() {
+      // enforce method constructor
+    }
+
+    public Builder setId(@Nullable String id) {
+      this.id = id;
+      return this;
+    }
+
+    public Builder setKey(@Nullable String key) {
+      this.key = key;
+      return this;
+    }
+
+    public Builder setFrom(String from) {
+      this.from = from;
+      return this;
+    }
+
+    public Builder setTo(String to) {
+      this.to = to;
+      return this;
+    }
+
+    public Builder setDryRun(boolean dryRun) {
+      this.dryRun = dryRun;
+      return this;
+    }
+
+    public BulkUpdateKeyRequest build() {
+      checkArgument(from != null && !from.isEmpty(), "The string to match must not be empty");
+      checkArgument(to != null && !to.isEmpty(), "The string replacement must not be empty");
+      return new BulkUpdateKeyRequest(this);
+    }
+  }
 }
index b643a9ab5c84185605b65554528df2272c87669e..4a66c029c4a2efdc767907eec954bcae8f758dcc 100644 (file)
@@ -31,7 +31,9 @@ import org.sonar.server.component.ComponentUpdater;
 import org.sonar.server.project.Visibility;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Projects.CreateWsResponse;
-import org.sonarqube.ws.client.project.CreateRequest;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 
 import static org.sonar.api.resources.Qualifiers.PROJECT;
 import static org.sonar.core.component.ComponentKeys.MAX_COMPONENT_KEY_LENGTH;
@@ -152,4 +154,91 @@ public class CreateAction implements ProjectsWsAction {
       .build();
   }
 
+  static class CreateRequest {
+
+    private final String organization;
+    private final String key;
+    private final String name;
+    private final String branch;
+    @CheckForNull
+    private final String visibility;
+
+    private CreateRequest(Builder builder) {
+      this.organization = builder.organization;
+      this.key = builder.key;
+      this.name = builder.name;
+      this.branch = builder.branch;
+      this.visibility = builder.visibility;
+    }
+
+    @CheckForNull
+    public String getOrganization() {
+      return organization;
+    }
+
+    @CheckForNull
+    public String getKey() {
+      return key;
+    }
+
+    @CheckForNull
+    public String getName() {
+      return name;
+    }
+
+    @CheckForNull
+    public String getBranch() {
+      return branch;
+    }
+
+    @CheckForNull
+    public String getVisibility() {
+      return visibility;
+    }
+
+    public static Builder builder() {
+      return new Builder();
+    }
+  }
+
+  static class Builder {
+    private String organization;
+    private String key;
+    private String name;
+    private String branch;
+    @CheckForNull
+    private String visibility;
+
+    private Builder() {
+    }
+
+    public Builder setOrganization(@Nullable String organization) {
+      this.organization = organization;
+      return this;
+    }
+
+    public Builder setKey(@Nullable String key) {
+      this.key = key;
+      return this;
+    }
+
+    public Builder setName(@Nullable String name) {
+      this.name = name;
+      return this;
+    }
+
+    public Builder setBranch(@Nullable String branch) {
+      this.branch = branch;
+      return this;
+    }
+
+    public Builder setVisibility(@Nullable String visibility) {
+      this.visibility = visibility;
+      return this;
+    }
+
+    public CreateRequest build() {
+      return new CreateRequest(this);
+    }
+  }
 }
index 48ce49927e7544e57f6de2a69ee3eab4c797adaa..e74a2e7c8377ccdc38489758e0ab59015a4eedf7 100644 (file)
@@ -36,7 +36,6 @@ public class ProjectsWsModule extends Module {
       GhostsAction.class,
       ProvisionedAction.class,
       SearchMyProjectsAction.class,
-      SearchMyProjectsDataLoader.class,
       SearchAction.class,
       UpdateVisibilityAction.class);
   }
index 9ef198b33b220371c84a49e206ed90818361c847..5f38d12164f621847a1315748a1edb6afbf91d04 100644 (file)
@@ -40,7 +40,6 @@ import org.sonar.db.permission.OrganizationPermission;
 import org.sonar.server.project.Visibility;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Projects.SearchWsResponse;
-import org.sonarqube.ws.client.project.SearchRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static org.sonar.api.resources.Qualifiers.APP;
index 95aabe985bddbdc778371c347eed3363c481280f..37867d57e77d932ead6a7e9278a5aac0d991d741 100644 (file)
  */
 package org.sonar.server.project.ws;
 
+import java.util.List;
 import java.util.function.Function;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.server.ws.Change;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.server.ws.WebService.Param;
+import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.ComponentLinkDto;
+import org.sonar.db.component.ComponentQuery;
+import org.sonar.db.component.SnapshotDto;
+import org.sonar.db.measure.MeasureDto;
+import org.sonar.db.measure.MeasureQuery;
+import org.sonar.db.metric.MetricDto;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Projects.SearchMyProjectsWsResponse;
 import org.sonarqube.ws.Projects.SearchMyProjectsWsResponse.Link;
 import org.sonarqube.ws.Projects.SearchMyProjectsWsResponse.Project;
-import org.sonarqube.ws.client.project.SearchMyProjectsRequest;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 
 import static com.google.common.base.Strings.emptyToNull;
 import static com.google.common.base.Strings.isNullOrEmpty;
+import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Paging.offset;
 import static org.sonar.core.util.Protobuf.setNullable;
+import static org.sonar.server.project.ws.SearchMyProjectsData.builder;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
 
 public class SearchMyProjectsAction implements ProjectsWsAction {
   private static final int MAX_SIZE = 500;
 
   private final DbClient dbClient;
-  private final SearchMyProjectsDataLoader dataLoader;
   private final UserSession userSession;
 
-  public SearchMyProjectsAction(DbClient dbClient, SearchMyProjectsDataLoader dataLoader, UserSession userSession) {
+  public SearchMyProjectsAction(DbClient dbClient, UserSession userSession) {
     this.dbClient = dbClient;
-    this.dataLoader = dataLoader;
     this.userSession = userSession;
   }
 
@@ -76,7 +92,7 @@ public class SearchMyProjectsAction implements ProjectsWsAction {
     checkAuthenticated();
 
     try (DbSession dbSession = dbClient.openSession(false)) {
-      SearchMyProjectsData data = dataLoader.load(dbSession, request);
+      SearchMyProjectsData data = load(dbSession, request);
       return buildResponse(request, data);
     }
   }
@@ -153,4 +169,99 @@ public class SearchMyProjectsAction implements ProjectsWsAction {
       return link.build();
     }
   }
+
+  SearchMyProjectsData load(DbSession dbSession, SearchMyProjectsRequest request) {
+    SearchMyProjectsData.Builder data = builder();
+    ProjectsResult searchResult = searchProjects(dbSession, request);
+    List<ComponentDto> projects = searchResult.projects;
+    List<String> projectUuids = Lists.transform(projects, ComponentDto::projectUuid);
+    List<ComponentLinkDto> projectLinks = dbClient.componentLinkDao().selectByComponentUuids(dbSession, projectUuids);
+    List<SnapshotDto> snapshots = dbClient.snapshotDao().selectLastAnalysesByRootComponentUuids(dbSession, projectUuids);
+    MetricDto gateStatusMetric = dbClient.metricDao().selectOrFailByKey(dbSession, CoreMetrics.ALERT_STATUS_KEY);
+    MeasureQuery measureQuery = MeasureQuery.builder()
+            .setProjectUuids(projectUuids)
+            .setMetricId(gateStatusMetric.getId())
+            .build();
+    List<MeasureDto> qualityGates = dbClient.measureDao().selectByQuery(dbSession, measureQuery);
+
+    data.setProjects(projects)
+            .setProjectLinks(projectLinks)
+            .setSnapshots(snapshots)
+            .setQualityGates(qualityGates)
+            .setTotalNbOfProjects(searchResult.total);
+
+    return data.build();
+  }
+
+  @VisibleForTesting
+  ProjectsResult searchProjects(DbSession dbSession, SearchMyProjectsRequest request) {
+    int userId = requireNonNull(userSession.getUserId(), "Current user must be authenticated");
+
+    List<Long> componentIds = dbClient.roleDao().selectComponentIdsByPermissionAndUserId(dbSession, UserRole.ADMIN, userId);
+    ComponentQuery dbQuery = ComponentQuery.builder()
+            .setQualifiers(Qualifiers.PROJECT)
+            .setComponentIds(ImmutableSet.copyOf(componentIds))
+            .build();
+
+    return new ProjectsResult(
+            dbClient.componentDao().selectByQuery(dbSession, dbQuery, offset(request.getPage(), request.getPageSize()), request.getPageSize()),
+            dbClient.componentDao().countByQuery(dbSession, dbQuery));
+  }
+
+  private static class ProjectsResult {
+    private final List<ComponentDto> projects;
+    private final int total;
+
+    private ProjectsResult(List<ComponentDto> projects, int total) {
+      this.projects = projects;
+      this.total = total;
+    }
+  }
+
+  private static class SearchMyProjectsRequest {
+    private final Integer page;
+    private final Integer pageSize;
+
+    private SearchMyProjectsRequest(Builder builder) {
+      this.page = builder.page;
+      this.pageSize = builder.pageSize;
+    }
+
+    @CheckForNull
+    public Integer getPage() {
+      return page;
+    }
+
+    @CheckForNull
+    public Integer getPageSize() {
+      return pageSize;
+    }
+
+    public static Builder builder() {
+      return new Builder();
+    }
+  }
+
+  private static class Builder {
+    private Integer page;
+    private Integer pageSize;
+
+    private Builder() {
+      // enforce method constructor
+    }
+
+    public Builder setPage(@Nullable Integer page) {
+      this.page = page;
+      return this;
+    }
+
+    public Builder setPageSize(@Nullable Integer pageSize) {
+      this.pageSize = pageSize;
+      return this;
+    }
+
+    public SearchMyProjectsRequest build() {
+      return new SearchMyProjectsRequest(this);
+    }
+  }
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchMyProjectsDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchMyProjectsDataLoader.java
deleted file mode 100644 (file)
index be0e663..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.project.ws;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import java.util.List;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.web.UserRole;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentLinkDto;
-import org.sonar.db.component.ComponentQuery;
-import org.sonar.db.component.SnapshotDto;
-import org.sonar.db.measure.MeasureDto;
-import org.sonar.db.measure.MeasureQuery;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.project.SearchMyProjectsRequest;
-
-import static java.util.Objects.requireNonNull;
-import static org.sonar.api.utils.Paging.offset;
-import static org.sonar.server.project.ws.SearchMyProjectsData.builder;
-
-public class SearchMyProjectsDataLoader {
-  private final UserSession userSession;
-  private final DbClient dbClient;
-
-  public SearchMyProjectsDataLoader(UserSession userSession, DbClient dbClient) {
-    this.userSession = userSession;
-    this.dbClient = dbClient;
-  }
-
-  SearchMyProjectsData load(DbSession dbSession, SearchMyProjectsRequest request) {
-    SearchMyProjectsData.Builder data = builder();
-    ProjectsResult searchResult = searchProjects(dbSession, request);
-    List<ComponentDto> projects = searchResult.projects;
-    List<String> projectUuids = Lists.transform(projects, ComponentDto::projectUuid);
-    List<ComponentLinkDto> projectLinks = dbClient.componentLinkDao().selectByComponentUuids(dbSession, projectUuids);
-    List<SnapshotDto> snapshots = dbClient.snapshotDao().selectLastAnalysesByRootComponentUuids(dbSession, projectUuids);
-    MetricDto gateStatusMetric = dbClient.metricDao().selectOrFailByKey(dbSession, CoreMetrics.ALERT_STATUS_KEY);
-    MeasureQuery measureQuery = MeasureQuery.builder()
-      .setProjectUuids(projectUuids)
-      .setMetricId(gateStatusMetric.getId())
-      .build();
-    List<MeasureDto> qualityGates = dbClient.measureDao().selectByQuery(dbSession, measureQuery);
-
-    data.setProjects(projects)
-      .setProjectLinks(projectLinks)
-      .setSnapshots(snapshots)
-      .setQualityGates(qualityGates)
-      .setTotalNbOfProjects(searchResult.total);
-
-    return data.build();
-  }
-
-  @VisibleForTesting
-  ProjectsResult searchProjects(DbSession dbSession, SearchMyProjectsRequest request) {
-    int userId = requireNonNull(userSession.getUserId(), "Current user must be authenticated");
-
-    List<Long> componentIds = dbClient.roleDao().selectComponentIdsByPermissionAndUserId(dbSession, UserRole.ADMIN, userId);
-    ComponentQuery dbQuery = ComponentQuery.builder()
-      .setQualifiers(Qualifiers.PROJECT)
-      .setComponentIds(ImmutableSet.copyOf(componentIds))
-      .build();
-
-    return new ProjectsResult(
-      dbClient.componentDao().selectByQuery(dbSession, dbQuery, offset(request.getPage(), request.getPageSize()), request.getPageSize()),
-      dbClient.componentDao().countByQuery(dbSession, dbQuery));
-  }
-
-  private static class ProjectsResult {
-    private final List<ComponentDto> projects;
-    private final int total;
-
-    private ProjectsResult(List<ComponentDto> projects, int total) {
-      this.projects = projects;
-      this.total = total;
-    }
-  }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchRequest.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchRequest.java
new file mode 100644 (file)
index 0000000..a725c86
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.project.ws;
+
+import java.util.List;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.sonar.api.resources.Qualifiers;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Collections.singletonList;
+import static java.util.Objects.requireNonNull;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.MAX_PAGE_SIZE;
+
+class SearchRequest {
+
+  private final String organization;
+  private final String query;
+  private final List<String> qualifiers;
+  private final String visibility;
+  private final Integer page;
+  private final Integer pageSize;
+  private final String analyzedBefore;
+  private final boolean onProvisionedOnly;
+  private final List<String> projects;
+  private final List<String> projectIds;
+
+  public SearchRequest(Builder builder) {
+    this.organization = builder.organization;
+    this.query = builder.query;
+    this.qualifiers = builder.qualifiers;
+    this.visibility = builder.visibility;
+    this.page = builder.page;
+    this.pageSize = builder.pageSize;
+    this.analyzedBefore = builder.analyzedBefore;
+    this.onProvisionedOnly = builder.onProvisionedOnly;
+    this.projects = builder.projects;
+    this.projectIds = builder.projectIds;
+  }
+
+  @CheckForNull
+  public String getOrganization() {
+    return organization;
+  }
+
+  public List<String> getQualifiers() {
+    return qualifiers;
+  }
+
+  @CheckForNull
+  public Integer getPage() {
+    return page;
+  }
+
+  @CheckForNull
+  public Integer getPageSize() {
+    return pageSize;
+  }
+
+  @CheckForNull
+  public String getQuery() {
+    return query;
+  }
+
+  @CheckForNull
+  public String getVisibility() {
+    return visibility;
+  }
+
+  @CheckForNull
+  public String getAnalyzedBefore() {
+    return analyzedBefore;
+  }
+
+  public boolean isOnProvisionedOnly() {
+    return onProvisionedOnly;
+  }
+
+  @CheckForNull
+  public List<String> getProjects() {
+    return projects;
+  }
+
+  @CheckForNull
+  public List<String> getProjectIds() {
+    return projectIds;
+  }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  public static class Builder {
+    private String organization;
+    private List<String> qualifiers = singletonList(Qualifiers.PROJECT);
+    private Integer page;
+    private Integer pageSize;
+    private String query;
+    private String visibility;
+    private String analyzedBefore;
+    private boolean onProvisionedOnly = false;
+    private List<String> projects;
+    private List<String> projectIds;
+
+    public Builder setOrganization(@Nullable String organization) {
+      this.organization = organization;
+      return this;
+    }
+
+    public Builder setQualifiers(List<String> qualifiers) {
+      this.qualifiers = requireNonNull(qualifiers, "Qualifiers cannot be null");
+      return this;
+    }
+
+    public Builder setPage(@Nullable Integer page) {
+      this.page = page;
+      return this;
+    }
+
+    public Builder setPageSize(@Nullable Integer pageSize) {
+      this.pageSize = pageSize;
+      return this;
+    }
+
+    public Builder setQuery(@Nullable String query) {
+      this.query = query;
+      return this;
+    }
+
+    public Builder setVisibility(@Nullable String visibility) {
+      this.visibility = visibility;
+      return this;
+    }
+
+    public Builder setAnalyzedBefore(@Nullable String lastAnalysisBefore) {
+      this.analyzedBefore = lastAnalysisBefore;
+      return this;
+    }
+
+    public Builder setOnProvisionedOnly(boolean onProvisionedOnly) {
+      this.onProvisionedOnly = onProvisionedOnly;
+      return this;
+    }
+
+    public Builder setProjects(@Nullable List<String> projects) {
+      this.projects = projects;
+      return this;
+    }
+
+    public Builder setProjectIds(@Nullable List<String> projectIds) {
+      this.projectIds = projectIds;
+      return this;
+    }
+
+    public SearchRequest build() {
+      checkArgument(projects==null || !projects.isEmpty(), "Project key list must not be empty");
+      checkArgument(projectIds==null || !projectIds.isEmpty(), "Project id list must not be empty");
+      checkArgument(pageSize == null || pageSize <= MAX_PAGE_SIZE, "Page size must not be greater than %s", MAX_PAGE_SIZE);
+      return new SearchRequest(this);
+    }
+  }
+}
index 49e79a01085b4cbc8db624777c2ce075ad323104..92d636dd97cabcfadc1dab339a122ebdbf12404c 100644 (file)
@@ -30,8 +30,11 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.component.ComponentFinder.ParamNames;
 import org.sonar.server.component.ComponentService;
-import org.sonarqube.ws.client.project.UpdateKeyRequest;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import static com.google.common.base.Preconditions.checkArgument;
 import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
 import static org.sonarqube.ws.client.project.ProjectsWsParameters.ACTION_UPDATE_KEY;
 import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_FROM;
@@ -111,4 +114,64 @@ public class UpdateKeyAction implements ProjectsWsAction {
       .setNewKey(request.mandatoryParam(PARAM_TO))
       .build();
   }
+
+  private static class UpdateKeyRequest {
+    private final String id;
+    private final String key;
+    private final String newKey;
+
+    public UpdateKeyRequest(Builder builder) {
+      this.id = builder.id;
+      this.key = builder.key;
+      this.newKey = builder.newKey;
+    }
+
+    @CheckForNull
+    public String getId() {
+      return id;
+    }
+
+    @CheckForNull
+    public String getKey() {
+      return key;
+    }
+
+    public String getNewKey() {
+      return newKey;
+    }
+
+    public static Builder builder() {
+      return new Builder();
+    }
+  }
+
+  private static class Builder {
+    private String id;
+    private String key;
+    private String newKey;
+
+    private Builder() {
+      // enforce method constructor
+    }
+
+    public Builder setId(@Nullable String id) {
+      this.id = id;
+      return this;
+    }
+
+    public Builder setKey(@Nullable String key) {
+      this.key = key;
+      return this;
+    }
+
+    public Builder setNewKey(String newKey) {
+      this.newKey = newKey;
+      return this;
+    }
+
+    public UpdateKeyRequest build() {
+      checkArgument(newKey != null && !newKey.isEmpty(), "The new key must not be empty");
+      return new UpdateKeyRequest(this);
+    }
+  }
 }
index 0fd7c05bfa6096dffbc32ae0ae333fd14bcf9a61..2128a1f32ec47fd17e0d81f836f6c8abf650a3c5 100644 (file)
@@ -42,7 +42,6 @@ import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.ProjectAnalyses.CreateEventResponse;
 import org.sonarqube.ws.ProjectAnalyses.Event;
-import org.sonarqube.ws.client.projectanalysis.CreateEventRequest;
 import org.sonarqube.ws.client.projectanalysis.EventCategory;
 
 import static com.google.common.base.Preconditions.checkArgument;
@@ -219,4 +218,65 @@ public class CreateEventAction implements ProjectAnalysesWsAction {
         throw new IllegalStateException("Event category not handled: " + request.getCategory());
     }
   }
+
+  private static class CreateEventRequest {
+    private final String analysis;
+    private final EventCategory category;
+    private final String name;
+
+    private CreateEventRequest(Builder builder) {
+      analysis = builder.analysis;
+      category = builder.category;
+      name = builder.name;
+    }
+
+    public String getAnalysis() {
+      return analysis;
+    }
+
+    public EventCategory getCategory() {
+      return category;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    public static Builder builder() {
+      return new Builder();
+    }
+  }
+
+  private static class Builder {
+    private String analysis;
+    private EventCategory category = EventCategory.OTHER;
+    private String name;
+
+    private Builder() {
+      // enforce static factory method
+    }
+
+    public Builder setAnalysis(String analysis) {
+      this.analysis = analysis;
+      return this;
+    }
+
+    public Builder setCategory(EventCategory category) {
+      this.category = category;
+      return this;
+    }
+
+    public Builder setName(String name) {
+      this.name = name;
+      return this;
+    }
+
+    public CreateEventRequest build() {
+      checkArgument(analysis != null, "Analysis key is required");
+      checkArgument(category != null, "Category is required");
+      checkArgument(name != null, "Name is required");
+
+      return new CreateEventRequest(this);
+    }
+  }
 }
index 713572437be2472dbc96e0e9ce1185e163560453..e7a66a3dc5b4920ff51ca6bb690879fe1214cd64 100644 (file)
@@ -19,9 +19,6 @@
  */
 package org.sonar.server.projectanalysis.ws;
 
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.stream.Stream;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
@@ -32,7 +29,6 @@ import org.sonar.db.DbSession;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.projectanalysis.DeleteRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.lang.String.format;
@@ -69,33 +65,21 @@ public class DeleteAction implements ProjectAnalysesWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
-    Stream.of(request)
-      .map(toWsRequest())
-      .forEach(deleteAnalysis());
+    String analysisParam = request.mandatoryParam(PARAM_ANALYSIS);
 
-    response.noContent();
-
-  }
-
-  private static Function<Request, DeleteRequest> toWsRequest() {
-    return request -> new DeleteRequest(request.mandatoryParam(PARAM_ANALYSIS));
-  }
-
-  private Consumer<DeleteRequest> deleteAnalysis() {
-    return request -> {
-      try (DbSession dbSession = dbClient.openSession(false)) {
-        SnapshotDto analysis = dbClient.snapshotDao().selectByUuid(dbSession, request.getAnalysis())
-          .orElseThrow(() -> analysisNotFoundException(request.getAnalysis()));
-        if (STATUS_UNPROCESSED.equals(analysis.getStatus())) {
-          throw analysisNotFoundException(request.getAnalysis());
-        }
-        userSession.checkComponentUuidPermission(UserRole.ADMIN, analysis.getComponentUuid());
-        checkArgument(!analysis.getLast(), "The last analysis '%s' cannot be deleted", request.getAnalysis());
-        analysis.setStatus(STATUS_UNPROCESSED);
-        dbClient.snapshotDao().update(dbSession, analysis);
-        dbSession.commit();
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      SnapshotDto analysis = dbClient.snapshotDao().selectByUuid(dbSession, analysisParam)
+        .orElseThrow(() -> analysisNotFoundException(analysisParam));
+      if (STATUS_UNPROCESSED.equals(analysis.getStatus())) {
+        throw analysisNotFoundException(analysisParam);
       }
-    };
+      userSession.checkComponentUuidPermission(UserRole.ADMIN, analysis.getComponentUuid());
+      checkArgument(!analysis.getLast(), "The last analysis '%s' cannot be deleted", analysisParam);
+      analysis.setStatus(STATUS_UNPROCESSED);
+      dbClient.snapshotDao().update(dbSession, analysis);
+      dbSession.commit();
+    }
+    response.noContent();
   }
 
   private static NotFoundException analysisNotFoundException(String analysis) {
index efd3a2b312cd4357b587cc8878d27824f8047a0a..087ff98fc1ec38eab7fdf06d25faf82f1311343b 100644 (file)
@@ -32,7 +32,6 @@ import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.event.EventDto;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.projectanalysis.DeleteEventRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.lang.String.format;
@@ -73,18 +72,14 @@ public class DeleteEventAction implements ProjectAnalysesWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
-    DeleteEventRequest deleteEventRequest = toDeleteEventRequest(request);
-    doHandle(deleteEventRequest);
-    response.noContent();
-  }
-
-  private void doHandle(DeleteEventRequest request) {
+    String eventP = request.mandatoryParam(PARAM_EVENT);
     try (DbSession dbSession = dbClient.openSession(false)) {
-      Stream.of(getEvent(dbSession, request.getEvent()))
-        .peek(checkPermissions())
-        .peek(checkModifiable())
-        .forEach(event -> deleteEvent(dbSession, event));
+      Stream.of(getEvent(dbSession, eventP))
+              .peek(checkPermissions())
+              .peek(checkModifiable())
+              .forEach(event -> deleteEvent(dbSession, event));
     }
+    response.noContent();
   }
 
   private EventDto getEvent(DbSession dbSession, String event) {
@@ -107,8 +102,4 @@ public class DeleteEventAction implements ProjectAnalysesWsAction {
   private Consumer<EventDto> checkPermissions() {
     return event -> userSession.checkComponentUuidPermission(UserRole.ADMIN, event.getComponentUuid());
   }
-
-  private static DeleteEventRequest toDeleteEventRequest(Request httpRequest) {
-    return new DeleteEventRequest(httpRequest.mandatoryParam(PARAM_EVENT));
-  }
 }
index 8729785236d2982819a54265ed0c0b3e16d1e575..204384812027e00bf2e12289fd1cf95b5dc02024 100644 (file)
@@ -41,7 +41,6 @@ import org.sonar.server.user.UserSession;
 import org.sonar.server.ws.KeyExamples;
 import org.sonarqube.ws.ProjectAnalyses;
 import org.sonarqube.ws.client.projectanalysis.EventCategory;
-import org.sonarqube.ws.client.projectanalysis.SearchRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static org.sonar.api.utils.DateUtils.parseEndingDateOrDateTime;
@@ -57,7 +56,7 @@ import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameter
 import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_FROM;
 import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_PROJECT;
 import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_TO;
-import static org.sonarqube.ws.client.projectanalysis.SearchRequest.DEFAULT_PAGE_SIZE;
+import static org.sonar.server.projectanalysis.ws.SearchRequest.DEFAULT_PAGE_SIZE;
 
 public class SearchAction implements ProjectAnalysesWsAction {
   private static final Set<String> ALLOWED_QUALIFIERS = ImmutableSet.of(Qualifiers.PROJECT, Qualifiers.APP, Qualifiers.VIEW);
index 233a59ca2c90facc4a682495ddc9dc43d5e88e80..5d19821135609ba8a2d48c3d277ee3e141c30791 100644 (file)
@@ -29,7 +29,6 @@ import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.event.EventDto;
-import org.sonarqube.ws.client.projectanalysis.SearchRequest;
 
 import static java.util.Objects.requireNonNull;
 
diff --git a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchRequest.java b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchRequest.java
new file mode 100644 (file)
index 0000000..d55ce27
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.projectanalysis.ws;
+
+import org.sonarqube.ws.client.projectanalysis.EventCategory;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
+
+class SearchRequest {
+  static final int DEFAULT_PAGE_SIZE = 100;
+  static final int MAX_SIZE = 500;
+
+  private final String project;
+  private final String branch;
+  private final EventCategory category;
+  private final int page;
+  private final int pageSize;
+  private final String from;
+  private final String to;
+
+  private SearchRequest(Builder builder) {
+    this.project = builder.project;
+    this.branch= builder.branch;
+    this.category = builder.category;
+    this.page = builder.page;
+    this.pageSize = builder.pageSize;
+    this.from = builder.from;
+    this.to = builder.to;
+  }
+
+  public String getProject() {
+    return project;
+  }
+
+  @CheckForNull
+  public String getBranch() {
+    return branch;
+  }
+
+  @CheckForNull
+  public EventCategory getCategory() {
+    return category;
+  }
+
+  public int getPage() {
+    return page;
+  }
+
+  public int getPageSize() {
+    return pageSize;
+  }
+
+  @CheckForNull
+  public String getFrom() {
+    return from;
+  }
+
+  @CheckForNull
+  public String getTo() {
+    return to;
+  }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  public static class Builder {
+    private String project;
+    private String branch;
+    private EventCategory category;
+    private int page = 1;
+    private int pageSize = DEFAULT_PAGE_SIZE;
+    private String from;
+    private String to;
+
+    private Builder() {
+      // enforce static factory method
+    }
+
+    public Builder setProject(String project) {
+      this.project = project;
+      return this;
+    }
+
+    public Builder setBranch(@Nullable String branch) {
+      this.branch = branch;
+      return this;
+    }
+
+    public Builder setCategory(@Nullable EventCategory category) {
+      this.category = category;
+      return this;
+    }
+
+    public Builder setPage(int page) {
+      this.page = page;
+      return this;
+    }
+
+    public Builder setPageSize(int pageSize) {
+      this.pageSize = pageSize;
+      return this;
+    }
+
+    public Builder setFrom(@Nullable String from) {
+      this.from = from;
+      return this;
+    }
+
+    public Builder setTo(@Nullable String to) {
+      this.to = to;
+      return this;
+    }
+
+    public SearchRequest build() {
+      requireNonNull(project, "Project is required");
+      checkArgument(pageSize <= MAX_SIZE, "Page size must be lower than or equal to " + MAX_SIZE);
+      return new SearchRequest(this);
+    }
+  }
+}
index e065f851b42f0aeb12bbc3103dd605875d995d3e..45164cb841e8ce702dccb1aa3eccde41c2d2710a 100644 (file)
@@ -38,10 +38,12 @@ import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.ProjectAnalyses.Event;
 import org.sonarqube.ws.ProjectAnalyses.UpdateEventResponse;
 import org.sonarqube.ws.client.projectanalysis.EventCategory;
-import org.sonarqube.ws.client.projectanalysis.UpdateEventRequest;
+
+import javax.annotation.CheckForNull;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
 import static org.apache.commons.lang.StringUtils.isNotBlank;
 import static org.sonar.core.util.Protobuf.setNullable;
 import static org.sonar.server.projectanalysis.ws.EventValidator.checkModifiable;
@@ -189,4 +191,23 @@ public class UpdateEventAction implements ProjectAnalysesWsAction {
       request.mandatoryParam(PARAM_EVENT),
       request.param(PARAM_NAME));
   }
+
+  private static class UpdateEventRequest {
+    private final String event;
+    private final String name;
+
+    public UpdateEventRequest(String event, String name) {
+      this.event = requireNonNull(event, "Event key is required");
+      this.name = requireNonNull(name, "Name is required");
+    }
+
+    public String getEvent() {
+      return event;
+    }
+
+    @CheckForNull
+    public String getName() {
+      return name;
+    }
+  }
 }
index 11f7a31009f314b6dbfaca8e76866dca9b79e75d..cc174920fd9796eb74e859a985e9869a3245c415 100644 (file)
@@ -31,7 +31,6 @@ import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.ProjectLinks;
 import org.sonarqube.ws.ProjectLinks.CreateWsResponse;
-import org.sonarqube.ws.client.projectlinks.CreateRequest;
 
 import static org.sonar.core.util.Slug.slugify;
 import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
@@ -147,4 +146,48 @@ public class CreateAction implements ProjectLinksWsAction {
     String slugified = slugify(name);
     return slugified.substring(0, Math.min(slugified.length(), LINK_TYPE_MAX_LENGTH));
   }
+
+  private static class CreateRequest {
+
+    private String name;
+    private String projectId;
+    private String projectKey;
+    private String url;
+
+    public CreateRequest setName(String name) {
+      this.name = name;
+      return this;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    public CreateRequest setProjectId(String projectId) {
+      this.projectId = projectId;
+      return this;
+    }
+
+    public String getProjectId() {
+      return projectId;
+    }
+
+    public CreateRequest setProjectKey(String projectKey) {
+      this.projectKey = projectKey;
+      return this;
+    }
+
+    public String getProjectKey() {
+      return projectKey;
+    }
+
+    public CreateRequest setUrl(String url) {
+      this.url = url;
+      return this;
+    }
+
+    public String getUrl() {
+      return url;
+    }
+  }
 }
index 243aac6040c70b17a4435a0e19e5c89e30c3eaea..05c90cb6530978a78df2859a449bd66eaf8adfbe 100644 (file)
@@ -28,7 +28,6 @@ import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentLinkDto;
 import org.sonar.server.user.UserSession;
 import org.sonar.server.ws.WsUtils;
-import org.sonarqube.ws.client.projectlinks.DeleteRequest;
 
 import static org.sonar.db.component.ComponentLinkDto.PROVIDED_TYPES;
 import static org.sonar.server.projectlink.ws.ProjectLinksWsParameters.ACTION_DELETE;
@@ -61,19 +60,13 @@ public class DeleteAction implements ProjectLinksWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
-    DeleteRequest deleteWsRequest = toDeleteWsRequest(request);
-    doHandle(deleteWsRequest);
+    doHandle(request.mandatoryParam(PARAM_ID));
     response.noContent();
   }
 
-  private static DeleteRequest toDeleteWsRequest(Request request) {
-    return new DeleteRequest()
-      .setId(request.mandatoryParam(PARAM_ID));
-  }
-
-  private void doHandle(DeleteRequest request) {
+  private void doHandle(String idParam) {
     try (DbSession dbSession = dbClient.openSession(false)) {
-      long id = Long.parseLong(request.getId());
+      long id = Long.parseLong(idParam);
       ComponentLinkDto link = dbClient.componentLinkDao().selectById(dbSession, id);
 
       link = WsUtils.checkFound(link, "Link with id '%s' not found", id);
index 0410d9c3f0181dccdbfa30646049a9182d4c3777..2a0a5644f770e82d6b755c270b691ea2b47dd7f3 100644 (file)
@@ -33,7 +33,6 @@ import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.ProjectLinks.Link;
 import org.sonarqube.ws.ProjectLinks.SearchWsResponse;
-import org.sonarqube.ws.client.projectlinks.SearchRequest;
 
 import static org.sonar.core.util.Protobuf.setNullable;
 import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
@@ -134,4 +133,28 @@ public class SearchAction implements ProjectLinksWsAction {
       .setProjectId(request.param(PARAM_PROJECT_ID))
       .setProjectKey(request.param(PARAM_PROJECT_KEY));
   }
+
+  private static class SearchRequest {
+
+    private String projectId;
+    private String projectKey;
+
+    public SearchRequest setProjectId(String projectId) {
+      this.projectId = projectId;
+      return this;
+    }
+
+    public String getProjectId() {
+      return projectId;
+    }
+
+    public SearchRequest setProjectKey(String projectKey) {
+      this.projectKey = projectKey;
+      return this;
+    }
+
+    public String getProjectKey() {
+      return projectKey;
+    }
+  }
 }
index c179b663a5656b233e48ec49e0f15dc2ca72a4ec..35f87da20b43837485695c87535469e128218bab 100644 (file)
@@ -37,8 +37,10 @@ import org.sonar.server.qualityprofile.QProfileResult;
 import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Qualityprofiles.CreateWsResponse;
-import org.sonarqube.ws.client.qualityprofile.CreateRequest;
 
+import javax.annotation.Nullable;
+
+import static com.google.common.base.Preconditions.checkArgument;
 import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
 import static org.sonar.server.qualityprofile.ws.QProfileWsSupport.createOrganizationParam;
 import static org.sonar.server.util.LanguageParamUtils.getLanguageKeys;
@@ -139,7 +141,7 @@ public class CreateAction implements QProfileWsAction {
   }
 
   private static CreateRequest toRequest(Request request, OrganizationDto organization) {
-    CreateRequest.Builder builder = CreateRequest.builder()
+    Builder builder = CreateRequest.builder()
       .setOrganizationKey(organization.getKey())
       .setLanguage(request.mandatoryParam(PARAM_LANGUAGE))
       .setName(request.mandatoryParam(PARAM_NAME));
@@ -168,4 +170,65 @@ public class CreateAction implements QProfileWsAction {
   private static String getBackupParamName(String importerKey) {
     return String.format(PARAM_BACKUP_FORMAT, importerKey);
   }
+
+  private static class CreateRequest {
+
+    private final String name;
+    private final String language;
+    private final String organizationKey;
+
+    private CreateRequest(Builder builder) {
+      this.name = builder.name;
+      this.language = builder.language;
+      this.organizationKey = builder.organizationKey;
+    }
+
+    public String getLanguage() {
+      return language;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    public String getOrganizationKey() {
+      return organizationKey;
+    }
+
+    public static Builder builder() {
+      return new Builder();
+    }
+  }
+
+  private static class Builder {
+    private String language;
+    private String name;
+    private String organizationKey;
+
+    private Builder() {
+      // enforce factory method use
+    }
+
+    public Builder setLanguage(@Nullable String language) {
+      this.language = language;
+      return this;
+    }
+
+    public Builder setName(@Nullable String profileName) {
+      this.name = profileName;
+      return this;
+    }
+
+    public Builder setOrganizationKey(@Nullable String organizationKey) {
+      this.organizationKey = organizationKey;
+      return this;
+    }
+
+    public CreateRequest build() {
+      checkArgument(language != null && !language.isEmpty(), "Language is mandatory and must not be empty.");
+      checkArgument(name != null && !name.isEmpty(), "Profile name is mandatory and must not be empty.");
+      checkArgument(organizationKey == null || !organizationKey.isEmpty(), "Organization key may be either null or not empty. Empty organization key is invalid.");
+      return new CreateRequest(this);
+    }
+  }
 }
index 892096abe07df34fe21462b9bb09ccbcfd83d16e..cd83b7f721f303f0c61cd22728620c41b862a468 100644 (file)
@@ -52,7 +52,6 @@ import org.sonar.server.user.UserSession;
 import org.sonar.server.util.LanguageParamUtils;
 import org.sonarqube.ws.Qualityprofiles.SearchWsResponse;
 import org.sonarqube.ws.Qualityprofiles.SearchWsResponse.QualityProfile;
-import org.sonarqube.ws.client.qualityprofile.SearchRequest;
 
 import static com.google.common.base.Preconditions.checkState;
 import static java.lang.String.format;
@@ -319,4 +318,59 @@ public class SearchAction implements QProfileWsAction {
     }
   }
 
+  private static class SearchRequest {
+    private String organizationKey;
+    private boolean defaults;
+    private String language;
+    private String qualityProfile;
+    private String projectKey;
+
+    public String getOrganizationKey() {
+      return organizationKey;
+    }
+
+    public SearchRequest setOrganizationKey(String organizationKey) {
+      this.organizationKey = organizationKey;
+      return this;
+    }
+
+    public boolean getDefaults() {
+      return defaults;
+    }
+
+    public SearchRequest setDefaults(boolean defaults) {
+      this.defaults = defaults;
+      return this;
+    }
+
+    @CheckForNull
+    public String getLanguage() {
+      return language;
+    }
+
+    public SearchRequest setLanguage(@Nullable String language) {
+      this.language = language;
+      return this;
+    }
+
+    @CheckForNull
+    public String getQualityProfile() {
+      return qualityProfile;
+    }
+
+    public SearchRequest setQualityProfile(@Nullable String qualityProfile) {
+      this.qualityProfile = qualityProfile;
+      return this;
+    }
+
+    @CheckForNull
+    public String getProjectKey() {
+      return projectKey;
+    }
+
+    public SearchRequest setProjectKey(@Nullable String projectKey) {
+      this.projectKey = projectKey;
+      return this;
+    }
+  }
 }
index 32fb6e74e6bc98711786b634e5506cc8df9e1e4c..dc2349efa8eb74df4a73ad4541d4d035aabb8631 100644 (file)
@@ -38,7 +38,6 @@ import org.sonar.db.qualityprofile.SearchGroupsQuery;
 import org.sonar.db.user.GroupDto;
 import org.sonarqube.ws.Common;
 import org.sonarqube.ws.Qualityprofiles;
-import org.sonarqube.ws.client.qualityprofile.SearchUsersRequest;
 
 import static org.sonar.api.server.ws.WebService.Param.PAGE;
 import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
index c0ab8247722fb5f027a170497e5f2c46bd9a5836..66dc3f4a1f6c780d32b294aeb554c41befec3677 100644 (file)
@@ -39,7 +39,6 @@ import org.sonar.db.user.UserDto;
 import org.sonar.server.issue.ws.AvatarResolver;
 import org.sonarqube.ws.Common;
 import org.sonarqube.ws.Qualityprofiles.SearchUsersResponse;
-import org.sonarqube.ws.client.qualityprofile.SearchUsersRequest;
 
 import static com.google.common.base.Strings.emptyToNull;
 import static org.sonar.api.server.ws.WebService.Param.PAGE;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchUsersRequest.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchUsersRequest.java
new file mode 100644 (file)
index 0000000..c606c88
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.qualityprofile.ws;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+class SearchUsersRequest {
+
+  private String organization;
+  private String qualityProfile;
+  private String language;
+  private String selected;
+  private String query;
+  private Integer page;
+  private Integer pageSize;
+
+  private SearchUsersRequest(Builder builder) {
+    this.organization = builder.organization;
+    this.qualityProfile = builder.qualityProfile;
+    this.language = builder.language;
+    this.selected = builder.selected;
+    this.query = builder.query;
+    this.page = builder.page;
+    this.pageSize = builder.pageSize;
+  }
+
+  @CheckForNull
+  public String getOrganization() {
+    return organization;
+  }
+
+  public String getQualityProfile() {
+    return qualityProfile;
+  }
+
+  public String getLanguage() {
+    return language;
+  }
+
+  @CheckForNull
+  public String getQuery() {
+    return query;
+  }
+
+  public String getSelected() {
+    return selected;
+  }
+
+  public Integer getPage() {
+    return page;
+  }
+
+  public Integer getPageSize() {
+    return pageSize;
+  }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  public static class Builder {
+    private String organization;
+    private String qualityProfile;
+    private String language;
+    private String selected;
+    private String query;
+    private Integer page;
+    private Integer pageSize;
+
+    public Builder setOrganization(@Nullable String organization) {
+      this.organization = organization;
+      return this;
+    }
+
+    public Builder setQualityProfile(String qualityProfile) {
+      this.qualityProfile = qualityProfile;
+      return this;
+    }
+
+    public Builder setLanguage(String language) {
+      this.language = language;
+      return this;
+    }
+
+    public Builder setSelected(String selected) {
+      this.selected = selected;
+      return this;
+    }
+
+    public Builder setQuery(@Nullable String query) {
+      this.query = query;
+      return this;
+    }
+
+    public Builder setPage(Integer page) {
+      this.page = page;
+      return this;
+    }
+
+    public Builder setPageSize(Integer pageSize) {
+      this.pageSize = pageSize;
+      return this;
+    }
+
+    public SearchUsersRequest build() {
+      return new SearchUsersRequest(this);
+    }
+  }
+}
index 348f30b5652b353a148db9ec079bd007cfa47444..a4486cbbd9f57dbbd221ae496c14d89825097a10 100644 (file)
@@ -58,7 +58,6 @@ import org.sonar.server.rule.index.RuleIndexDefinition;
 import org.sonar.server.rule.index.RuleQuery;
 import org.sonarqube.ws.Common;
 import org.sonarqube.ws.Rules.SearchResponse;
-import org.sonarqube.ws.client.rules.SearchRequest;
 
 import static java.lang.String.format;
 import static org.sonar.api.server.ws.WebService.Param.ASCENDING;
@@ -448,27 +447,18 @@ public class SearchAction implements RulesWsAction {
   }
 
   private static SearchRequest toSearchWsRequest(Request request) {
+    request.mandatoryParamAsBoolean(ASCENDING);
     return new SearchRequest()
-      .setActivation("" + request.paramAsBoolean(PARAM_ACTIVATION))
       .setActiveSeverities(request.paramAsStrings(PARAM_ACTIVE_SEVERITIES))
-      .setAsc("" + request.mandatoryParamAsBoolean(ASCENDING))
-      .setAvailableSince(request.param(PARAM_AVAILABLE_SINCE))
       .setF(request.paramAsStrings(FIELDS))
       .setFacets(request.paramAsStrings(FACETS))
-      .setInheritance(request.paramAsStrings(PARAM_INHERITANCE))
-      .setIsTemplate("" + request.paramAsBoolean(PARAM_IS_TEMPLATE))
       .setLanguages(request.paramAsStrings(PARAM_LANGUAGES))
       .setP("" + request.mandatoryParamAsInt(PAGE))
       .setPs("" + request.mandatoryParamAsInt(PAGE_SIZE))
-      .setQ(request.param(TEXT_QUERY))
-      .setQprofile(request.param(PARAM_QPROFILE))
       .setRepositories(request.paramAsStrings(PARAM_REPOSITORIES))
-      .setRuleKey(request.param(PARAM_RULE_KEY))
-      .setS(request.param(SORT))
       .setSeverities(request.paramAsStrings(PARAM_SEVERITIES))
       .setStatuses(request.paramAsStrings(PARAM_STATUSES))
       .setTags(request.paramAsStrings(PARAM_TAGS))
-      .setTemplateKey(request.param(PARAM_TEMPLATE_KEY))
       .setTypes(request.paramAsStrings(PARAM_TYPES));
   }
 
@@ -539,4 +529,117 @@ public class SearchAction implements RulesWsAction {
     }
   }
 
+  private static class SearchRequest {
+
+    private List<String> activeSeverities;
+    private List<String> f;
+    private List<String> facets;
+    private List<String> languages;
+    private String p;
+    private String ps;
+    private List<String> repositories;
+    private List<String> severities;
+    private List<String> statuses;
+    private List<String> tags;
+    private List<String> types;
+
+    private SearchRequest setActiveSeverities(List<String> activeSeverities) {
+      this.activeSeverities = activeSeverities;
+      return this;
+    }
+
+    private List<String> getActiveSeverities() {
+      return activeSeverities;
+    }
+
+    private SearchRequest setF(List<String> f) {
+      this.f = f;
+      return this;
+    }
+
+    private List<String> getF() {
+      return f;
+    }
+
+    private SearchRequest setFacets(List<String> facets) {
+      this.facets = facets;
+      return this;
+    }
+
+    private List<String> getFacets() {
+      return facets;
+    }
+
+    private SearchRequest setLanguages(List<String> languages) {
+      this.languages = languages;
+      return this;
+    }
+
+    private List<String> getLanguages() {
+      return languages;
+    }
+
+    private SearchRequest setP(String p) {
+      this.p = p;
+      return this;
+    }
+
+    private String getP() {
+      return p;
+    }
+
+    private SearchRequest setPs(String ps) {
+      this.ps = ps;
+      return this;
+    }
+
+    private String getPs() {
+      return ps;
+    }
+
+    private SearchRequest setRepositories(List<String> repositories) {
+      this.repositories = repositories;
+      return this;
+    }
+
+    private List<String> getRepositories() {
+      return repositories;
+    }
+
+    private SearchRequest setSeverities(List<String> severities) {
+      this.severities = severities;
+      return this;
+    }
+
+    private List<String> getSeverities() {
+      return severities;
+    }
+
+    private SearchRequest setStatuses(List<String> statuses) {
+      this.statuses = statuses;
+      return this;
+    }
+
+    private List<String> getStatuses() {
+      return statuses;
+    }
+
+    private SearchRequest setTags(List<String> tags) {
+      this.tags = tags;
+      return this;
+    }
+
+    private List<String> getTags() {
+      return tags;
+    }
+
+    private SearchRequest setTypes(List<String> types) {
+      this.types = types;
+      return this;
+    }
+
+    private List<String> getTypes() {
+      return types;
+    }
+  }
 }
index 35d78cc6c27b77b1db96ee4816a545ff7f91fe6c..9e91afe3cd3a95f61edca6ad6a335efc80c3e015 100644 (file)
@@ -34,7 +34,6 @@ import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Settings;
 import org.sonarqube.ws.Settings.ListDefinitionsWsResponse;
-import org.sonarqube.ws.client.settings.ListDefinitionsRequest;
 
 import static com.google.common.base.Strings.emptyToNull;
 import static java.util.Comparator.comparing;
@@ -161,4 +160,27 @@ public class ListDefinitionsAction implements SettingsWsAction {
       .build();
   }
 
+  private static class ListDefinitionsRequest {
+
+    private String branch;
+    private String component;
+
+    public ListDefinitionsRequest setBranch(String branch) {
+      this.branch = branch;
+      return this;
+    }
+
+    public String getBranch() {
+      return branch;
+    }
+
+    public ListDefinitionsRequest setComponent(String component) {
+      this.component = component;
+      return this;
+    }
+
+    public String getComponent() {
+      return component;
+    }
+  }
 }
index 27f89a4fc852f8cdac459551a894bbd6ddff5bbb..b8854c487a20f872da53399a721d20b9fec27728 100644 (file)
@@ -36,7 +36,6 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.setting.ws.SettingValidations.SettingData;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.settings.ResetRequest;
 
 import static java.util.Collections.emptyList;
 import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
@@ -146,4 +145,38 @@ public class ResetAction implements SettingsWsAction {
       userSession.checkIsSystemAdministrator();
     }
   }
+
+  private static class ResetRequest {
+
+    private String branch;
+    private String component;
+    private List<String> keys;
+
+    public ResetRequest setBranch(String branch) {
+      this.branch = branch;
+      return this;
+    }
+
+    public String getBranch() {
+      return branch;
+    }
+
+    public ResetRequest setComponent(String component) {
+      this.component = component;
+      return this;
+    }
+
+    public String getComponent() {
+      return component;
+    }
+
+    public ResetRequest setKeys(List<String> keys) {
+      this.keys = keys;
+      return this;
+    }
+
+    public List<String> getKeys() {
+      return keys;
+    }
+  }
 }
index 8eb5a128a4242ad588eb7b4cd3486873146fe03b..b652a39dbcc761afa775bfbe18cd54b864a4a134 100644 (file)
@@ -54,10 +54,10 @@ import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.platform.SettingsChangeNotifier;
 import org.sonar.server.setting.ws.SettingValidations.SettingData;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.settings.SetRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.lang.String.format;
+import static org.apache.commons.lang.StringUtils.isNotEmpty;
 import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
 import static org.sonar.server.ws.WsUtils.checkRequest;
 import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_BRANCH;
@@ -282,13 +282,17 @@ public class SetAction implements SettingsWsAction {
   }
 
   private static SetRequest toWsRequest(Request request) {
-    return new SetRequest()
+    SetRequest set = new SetRequest()
       .setKey(request.mandatoryParam(PARAM_KEY))
       .setValue(request.param(PARAM_VALUE))
       .setValues(request.multiParam(PARAM_VALUES))
       .setFieldValues(request.multiParam(PARAM_FIELD_VALUES))
       .setComponent(request.param(PARAM_COMPONENT))
       .setBranch(request.param(PARAM_BRANCH));
+    checkArgument(isNotEmpty(set.getKey()), "Setting key is mandatory and must not be empty");
+    checkArgument(set.getValues() != null, "Setting values must not be null");
+    checkArgument(set.getFieldValues() != null, "Setting fields values must not be null");
+    return set;
   }
 
   private static Map<String, String> readOneFieldValues(String json, String key) {
@@ -338,4 +342,68 @@ public class SetAction implements SettingsWsAction {
       this.value = value;
     }
   }
+
+  private static class SetRequest {
+
+    private String branch;
+    private String component;
+    private List<String> fieldValues;
+    private String key;
+    private String value;
+    private List<String> values;
+
+    public SetRequest setBranch(String branch) {
+      this.branch = branch;
+      return this;
+    }
+
+    public String getBranch() {
+      return branch;
+    }
+
+    public SetRequest setComponent(String component) {
+      this.component = component;
+      return this;
+    }
+
+    public String getComponent() {
+      return component;
+    }
+
+    public SetRequest setFieldValues(List<String> fieldValues) {
+      this.fieldValues = fieldValues;
+      return this;
+    }
+
+    public List<String> getFieldValues() {
+      return fieldValues;
+    }
+
+    public SetRequest setKey(String key) {
+      this.key = key;
+      return this;
+    }
+
+    public String getKey() {
+      return key;
+    }
+
+    public SetRequest setValue(String value) {
+      this.value = value;
+      return this;
+    }
+
+    public String getValue() {
+      return value;
+    }
+
+    public SetRequest setValues(List<String> values) {
+      this.values = values;
+      return this;
+    }
+
+    public List<String> getValues() {
+      return values;
+    }
+  }
 }
index 5c50aeed676d9ae2d75da8b31ed1e71ebcddfaed..e98c1df0462010e7052a4827f165d72876a15a59 100644 (file)
@@ -42,7 +42,6 @@ import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Settings;
 import org.sonarqube.ws.Settings.ValuesWsResponse;
-import org.sonarqube.ws.client.settings.ValuesRequest;
 
 import static java.lang.String.format;
 import static java.util.stream.Stream.concat;
@@ -139,7 +138,7 @@ public class ValuesAction implements SettingsWsAction {
 
   private Set<String> loadKeys(ValuesRequest valuesRequest) {
     List<String> keys = valuesRequest.getKeys();
-    return keys.isEmpty() ? concat(propertyDefinitions.getAll().stream().map(PropertyDefinition::key), SERVER_SETTING_KEYS.stream()).collect(Collectors.toSet())
+    return keys == null || keys.isEmpty() ? concat(propertyDefinitions.getAll().stream().map(PropertyDefinition::key), SERVER_SETTING_KEYS.stream()).collect(Collectors.toSet())
       : ImmutableSet.copyOf(keys);
   }
 
@@ -290,4 +289,37 @@ public class ValuesAction implements SettingsWsAction {
     }
   }
 
+  private static class ValuesRequest {
+
+    private String branch;
+    private String component;
+    private List<String> keys;
+
+    public ValuesRequest setBranch(String branch) {
+      this.branch = branch;
+      return this;
+    }
+
+    public String getBranch() {
+      return branch;
+    }
+
+    public ValuesRequest setComponent(String component) {
+      this.component = component;
+      return this;
+    }
+
+    public String getComponent() {
+      return component;
+    }
+
+    public ValuesRequest setKeys(List<String> keys) {
+      this.keys = keys;
+      return this;
+    }
+
+    public List<String> getKeys() {
+      return keys;
+    }
+  }
 }
index df3409fd416acf36d5ac54456e6e02296d32ee3a..626d03fe998746cfb764f1c0eae509709fba7934 100644 (file)
@@ -33,9 +33,14 @@ import org.sonar.server.user.NewUser;
 import org.sonar.server.user.UserSession;
 import org.sonar.server.user.UserUpdater;
 import org.sonarqube.ws.Users.CreateWsResponse;
-import org.sonarqube.ws.client.user.CreateRequest;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Strings.emptyToNull;
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static java.util.Collections.emptyList;
 import static org.sonar.core.util.Protobuf.setNullable;
 import static org.sonar.server.user.ExternalIdentity.SQ_AUTHORITY;
 import static org.sonar.server.user.UserUpdater.EMAIL_MAX_LENGTH;
@@ -167,4 +172,104 @@ public class CreateAction implements UsersWsAction {
     List<String> oldScmAccounts = request.paramAsStrings(PARAM_SCM_ACCOUNTS);
     return oldScmAccounts != null ? oldScmAccounts : Collections.emptyList();
   }
+
+  static class CreateRequest {
+
+    private final String login;
+    private final String password;
+    private final String name;
+    private final String email;
+    private final List<String> scmAccounts;
+    private final boolean local;
+
+    private CreateRequest(Builder builder) {
+      this.login = builder.login;
+      this.password = builder.password;
+      this.name = builder.name;
+      this.email = builder.email;
+      this.scmAccounts = builder.scmAccounts;
+      this.local = builder.local;
+    }
+
+    public String getLogin() {
+      return login;
+    }
+
+    @CheckForNull
+    public String getPassword() {
+      return password;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    @CheckForNull
+    public String getEmail() {
+      return email;
+    }
+
+    public List<String> getScmAccounts() {
+      return scmAccounts;
+    }
+
+    public boolean isLocal() {
+      return local;
+    }
+
+    public static Builder builder() {
+      return new Builder();
+    }
+  }
+
+  static class Builder {
+    private String login;
+    private String password;
+    private String name;
+    private String email;
+    private List<String> scmAccounts = emptyList();
+    private boolean local = true;
+
+    private Builder() {
+      // enforce factory method use
+    }
+
+    public Builder setLogin(String login) {
+      this.login = login;
+      return this;
+    }
+
+    public Builder setPassword(@Nullable String password) {
+      this.password = password;
+      return this;
+    }
+
+    public Builder setName(String name) {
+      this.name = name;
+      return this;
+    }
+
+    public Builder setEmail(@Nullable String email) {
+      this.email = email;
+      return this;
+    }
+
+    public Builder setScmAccounts(List<String> scmAccounts) {
+      this.scmAccounts = scmAccounts;
+      return this;
+    }
+
+    public Builder setLocal(boolean local) {
+      this.local = local;
+      return this;
+    }
+
+    public CreateRequest build() {
+      checkArgument(!isNullOrEmpty(login), "Login is mandatory and must not be empty");
+      checkArgument(!isNullOrEmpty(name), "Name is mandatory and must not be empty");
+      checkArgument(!local || !isNullOrEmpty(password), "Password is mandatory and must not be empty");
+      checkArgument(local || isNullOrEmpty(password), "Password should only be set on local user");
+      return new CreateRequest(this);
+    }
+  }
 }
index e12438d042d23d1f0a7703cd84af1c1ecc6bdbca..944d538595137356650d64b3b15301fc9d999b9f 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.server.user.ws;
 
 import java.util.List;
 import java.util.Optional;
+import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.server.ws.Change;
 import org.sonar.api.server.ws.Request;
@@ -43,9 +44,9 @@ import org.sonar.server.user.UserSession;
 import org.sonar.server.usergroups.DefaultGroupFinder;
 import org.sonarqube.ws.Users.GroupsWsResponse;
 import org.sonarqube.ws.Users.GroupsWsResponse.Group;
-import org.sonarqube.ws.client.user.GroupsRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Strings.isNullOrEmpty;
 import static org.sonar.api.server.ws.WebService.Param.PAGE;
 import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
 import static org.sonar.api.server.ws.WebService.Param.SELECTED;
@@ -179,4 +180,103 @@ public class GroupsAction implements UsersWsAction {
     return groupBuilder.build();
   }
 
+  private static class GroupsRequest {
+
+    private final String login;
+    private final String organization;
+    private final String query;
+    private final String selected;
+    private final Integer page;
+    private final Integer pageSize;
+
+    private GroupsRequest(Builder builder) {
+      this.login = builder.login;
+      this.organization = builder.organization;
+      this.query = builder.query;
+      this.selected = builder.selected;
+      this.page = builder.page;
+      this.pageSize = builder.pageSize;
+    }
+
+    public String getLogin() {
+      return login;
+    }
+
+    @CheckForNull
+    public String getOrganization() {
+      return organization;
+    }
+
+    @CheckForNull
+    public String getQuery() {
+      return query;
+    }
+
+    @CheckForNull
+    public String getSelected() {
+      return selected;
+    }
+
+    @CheckForNull
+    public Integer getPage() {
+      return page;
+    }
+
+    @CheckForNull
+    public Integer getPageSize() {
+      return pageSize;
+    }
+
+    public static Builder builder() {
+      return new Builder();
+    }
+  }
+
+  private static class Builder {
+    private String login;
+    private String organization;
+    private String query;
+    private String selected;
+    private Integer page;
+    private Integer pageSize;
+
+    private Builder() {
+      // enforce factory method use
+    }
+
+    public Builder setLogin(String login) {
+      this.login = login;
+      return this;
+    }
+
+    public Builder setOrganization(@Nullable String organization) {
+      this.organization = organization;
+      return this;
+    }
+
+    public Builder setQuery(@Nullable String query) {
+      this.query = query;
+      return this;
+    }
+
+    public Builder setSelected(@Nullable String selected) {
+      this.selected = selected;
+      return this;
+    }
+
+    public Builder setPage(@Nullable Integer page) {
+      this.page = page;
+      return this;
+    }
+
+    public Builder setPageSize(@Nullable Integer pageSize) {
+      this.pageSize = pageSize;
+      return this;
+    }
+
+    public GroupsRequest build() {
+      checkArgument(!isNullOrEmpty(login), "Login is mandatory and must not be empty");
+      return new GroupsRequest(this);
+    }
+  }
 }
index f10ba7f7378e8f21ba3d66779059c781e9b36c45..58e0233aa29bbf99898d548105c07f37ac66e9f0 100644 (file)
 package org.sonar.server.user.ws;
 
 import com.google.common.collect.Multimap;
+
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
+import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.server.ws.Change;
 import org.sonar.api.server.ws.Request;
@@ -42,7 +45,6 @@ import org.sonar.server.user.index.UserIndex;
 import org.sonar.server.user.index.UserQuery;
 import org.sonarqube.ws.Users;
 import org.sonarqube.ws.Users.SearchWsResponse;
-import org.sonarqube.ws.client.user.SearchRequest;
 
 import static com.google.common.base.MoreObjects.firstNonNull;
 import static com.google.common.base.Preconditions.checkArgument;
@@ -188,4 +190,76 @@ public class SearchAction implements UsersWsAction {
       .build();
   }
 
+  private static class SearchRequest {
+
+    private final Integer page;
+    private final Integer pageSize;
+    private final String query;
+    private final List<String> possibleFields;
+
+    private SearchRequest(Builder builder) {
+      this.page = builder.page;
+      this.pageSize = builder.pageSize;
+      this.query = builder.query;
+      this.possibleFields = builder.additionalFields;
+    }
+
+    @CheckForNull
+    public Integer getPage() {
+      return page;
+    }
+
+    @CheckForNull
+    public Integer getPageSize() {
+      return pageSize;
+    }
+
+    @CheckForNull
+    public String getQuery() {
+      return query;
+    }
+
+    public List<String> getPossibleFields() {
+      return possibleFields;
+    }
+
+    public static Builder builder() {
+      return new Builder();
+    }
+  }
+
+  private static class Builder {
+    private Integer page;
+    private Integer pageSize;
+    private String query;
+    private List<String> additionalFields = new ArrayList<>();
+
+    private Builder() {
+      // enforce factory method use
+    }
+
+    public Builder setPage(@Nullable Integer page) {
+      this.page = page;
+      return this;
+    }
+
+    public Builder setPageSize(@Nullable Integer pageSize) {
+      this.pageSize = pageSize;
+      return this;
+    }
+
+    public Builder setQuery(@Nullable String query) {
+      this.query = query;
+      return this;
+    }
+
+    public Builder setPossibleFields(List<String> possibleFields) {
+      this.additionalFields = possibleFields;
+      return this;
+    }
+
+    public SearchRequest build() {
+      return new SearchRequest(this);
+    }
+  }
 }
index bfe70c5200438462a5b518e0ba9a1120f5fc7ab9..5bf910b169f021c7579e2ec80d772bb7f36318df 100644 (file)
@@ -34,9 +34,14 @@ import org.sonar.db.user.UserDto;
 import org.sonar.server.user.UpdateUser;
 import org.sonar.server.user.UserSession;
 import org.sonar.server.user.UserUpdater;
-import org.sonarqube.ws.client.user.UpdateRequest;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Strings.emptyToNull;
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static java.util.Collections.emptyList;
 import static java.util.Collections.singletonList;
 import static org.sonar.server.user.UserUpdater.EMAIL_MAX_LENGTH;
 import static org.sonar.server.user.UserUpdater.LOGIN_MAX_LENGTH;
@@ -155,4 +160,77 @@ public class UpdateAction implements UsersWsAction {
     List<String> oldScmAccounts = request.paramAsStrings(PARAM_SCM_ACCOUNTS);
     return oldScmAccounts != null ? oldScmAccounts : new ArrayList<>();
   }
+
+  private static class UpdateRequest {
+
+    private final String login;
+    private final String name;
+    private final String email;
+    private final List<String> scmAccounts;
+
+    private UpdateRequest(Builder builder) {
+      this.login = builder.login;
+      this.name = builder.name;
+      this.email = builder.email;
+      this.scmAccounts = builder.scmAccounts;
+    }
+
+    public String getLogin() {
+      return login;
+    }
+
+    @CheckForNull
+    public String getName() {
+      return name;
+    }
+
+    @CheckForNull
+    public String getEmail() {
+      return email;
+    }
+
+    public List<String> getScmAccounts() {
+      return scmAccounts;
+    }
+
+    public static Builder builder() {
+      return new Builder();
+    }
+  }
+
+  private static class Builder {
+    private String login;
+    private String name;
+    private String email;
+    private List<String> scmAccounts = emptyList();
+
+    private Builder() {
+      // enforce factory method use
+    }
+
+    public Builder setLogin(String login) {
+      this.login = login;
+      return this;
+    }
+
+    public Builder setName(@Nullable String name) {
+      this.name = name;
+      return this;
+    }
+
+    public Builder setEmail(@Nullable String email) {
+      this.email = email;
+      return this;
+    }
+
+    public Builder setScmAccounts(List<String> scmAccounts) {
+      this.scmAccounts = scmAccounts;
+      return this;
+    }
+
+    public UpdateRequest build() {
+      checkArgument(!isNullOrEmpty(login), "Login is mandatory and must not be empty");
+      return new UpdateRequest(this);
+    }
+  }
 }
index 02973e250cb57e2e2541940402d090f6757a1d5f..1a980db0856c9d96f394e38490de621a5dcab9be 100644 (file)
@@ -33,7 +33,6 @@ import org.sonar.server.user.UserSession;
 import org.sonar.server.usertoken.TokenGenerator;
 import org.sonarqube.ws.UserTokens;
 import org.sonarqube.ws.UserTokens.GenerateWsResponse;
-import org.sonarqube.ws.client.usertokens.GenerateRequest;
 
 import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
 import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
@@ -155,4 +154,28 @@ public class GenerateAction implements UserTokensWsAction {
       .setToken(token)
       .build();
   }
+
+  private static class GenerateRequest {
+
+    private String login;
+    private String name;
+
+    public GenerateRequest setLogin(String login) {
+      this.login = login;
+      return this;
+    }
+
+    public String getLogin() {
+      return login;
+    }
+
+    public GenerateRequest setName(String name) {
+      this.name = name;
+      return this;
+    }
+
+    public String getName() {
+      return name;
+    }
+  }
 }
index fe828f6b41146a37b3a7ba40d65b08ef2eee9b8c..c73673ada17eb33486ce55fca0babbe51d6af28e 100644 (file)
@@ -25,7 +25,6 @@ import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.client.usertokens.RevokeRequest;
 
 import static org.sonar.server.usertoken.ws.UserTokensWsParameters.ACTION_REVOKE;
 import static org.sonar.server.usertoken.ws.UserTokensWsParameters.PARAM_LOGIN;
@@ -61,26 +60,18 @@ public class RevokeAction implements UserTokensWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
-    doHandle(toRevokeRequest(request));
-    response.noContent();
-  }
+    String login = request.param(PARAM_LOGIN);
+    if (login == null) {
+      login = userSession.getLogin();
+    }
+    String name = request.mandatoryParam(PARAM_NAME);
 
-  private void doHandle(RevokeRequest request) {
-    TokenPermissionsValidator.validate(userSession, request.getLogin());
+    TokenPermissionsValidator.validate(userSession, login);
 
     try (DbSession dbSession = dbClient.openSession(false)) {
-      dbClient.userTokenDao().deleteByLoginAndName(dbSession, request.getLogin(), request.getName());
+      dbClient.userTokenDao().deleteByLoginAndName(dbSession, login, name);
       dbSession.commit();
     }
-  }
-
-  private RevokeRequest toRevokeRequest(Request request) {
-    RevokeRequest RevokeRequest = new RevokeRequest()
-      .setLogin(request.param(PARAM_LOGIN))
-      .setName(request.mandatoryParam(PARAM_NAME));
-    if (RevokeRequest.getLogin() == null) {
-      RevokeRequest.setLogin(userSession.getLogin());
-    }
-    return RevokeRequest;
+    response.noContent();
   }
 }
index e946788bfaeb4ae2f1c63af8c4b8518b5976c5b6..a2472b494325e2b25ec7ef36856432b50b8cb1e9 100644 (file)
@@ -29,7 +29,6 @@ import org.sonar.db.DbSession;
 import org.sonar.db.user.UserTokenDto;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.UserTokens.SearchWsResponse;
-import org.sonarqube.ws.client.usertokens.SearchRequest;
 
 import static org.sonar.api.utils.DateUtils.formatDateTime;
 import static org.sonar.server.ws.WsUtils.checkFound;
@@ -63,29 +62,24 @@ public class SearchAction implements UserTokensWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
-    SearchWsResponse searchWsResponse = doHandle(toSearchRequest(request));
+    String login = request.param(PARAM_LOGIN);
+    if (login == null) {
+      login = userSession.getLogin();
+    }
+    SearchWsResponse searchWsResponse = doHandle(login);
     writeProtobuf(searchWsResponse, request, response);
   }
 
-  private SearchWsResponse doHandle(SearchRequest request) {
-    TokenPermissionsValidator.validate(userSession, request.getLogin());
+  private SearchWsResponse doHandle(String login) {
+    TokenPermissionsValidator.validate(userSession, login);
 
     try (DbSession dbSession = dbClient.openSession(false)) {
-      String login = request.getLogin();
       checkLoginExists(dbSession, login);
       List<UserTokenDto> userTokens = dbClient.userTokenDao().selectByLogin(dbSession, login);
       return buildResponse(login, userTokens);
     }
   }
 
-  private SearchRequest toSearchRequest(Request request) {
-    SearchRequest SearchRequest = new SearchRequest().setLogin(request.param(PARAM_LOGIN));
-    if (SearchRequest.getLogin() == null) {
-      SearchRequest.setLogin(userSession.getLogin());
-    }
-    return SearchRequest;
-  }
-
   private static SearchWsResponse buildResponse(String login, List<UserTokenDto> userTokensDto) {
     SearchWsResponse.Builder searchWsResponse = SearchWsResponse.newBuilder();
     SearchWsResponse.UserToken.Builder userTokenBuilder = SearchWsResponse.UserToken.newBuilder();
index 2a94d9e999d29cabb9864b39de402770868bb79a..a23bc3338c2f32e20623121a102a0d256be75ce6 100644 (file)
@@ -53,7 +53,7 @@ import org.sonar.server.ws.WsActionTester;
 import org.sonarqube.ws.MediaTypes;
 import org.sonarqube.ws.Components.Component;
 import org.sonarqube.ws.Components.SearchWsResponse;
-import org.sonarqube.ws.client.component.SearchRequest;
+import org.sonar.server.component.ws.SearchAction.SearchRequest;
 
 import static java.util.Arrays.asList;
 import static java.util.Collections.emptySet;
index 2f2a6d1ac9e0cb97d9e8335eff2ec841bb94625d..77ba51d4a7ec888f234308364fb861b4598f4f14 100644 (file)
@@ -46,6 +46,8 @@ import org.sonar.db.measure.MeasureDto;
 import org.sonar.db.metric.MetricDto;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.property.PropertyDto;
+import org.sonar.server.component.ws.SearchProjectsAction.RequestBuilder;
+import org.sonar.server.component.ws.SearchProjectsAction.SearchProjectsRequest;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.measure.index.ProjectMeasuresIndex;
 import org.sonar.server.measure.index.ProjectMeasuresIndexDefinition;
@@ -59,7 +61,6 @@ import org.sonar.server.ws.WsActionTester;
 import org.sonarqube.ws.Common;
 import org.sonarqube.ws.Components.Component;
 import org.sonarqube.ws.Components.SearchProjectsWsResponse;
-import org.sonarqube.ws.client.component.SearchProjectsRequest;
 
 import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
@@ -134,7 +135,7 @@ public class SearchProjectsActionTest {
   private WsActionTester ws = new WsActionTester(
     new SearchProjectsAction(dbClient, index, userSession));
 
-  private SearchProjectsRequest.Builder request = SearchProjectsRequest.builder();
+  private RequestBuilder request = SearchProjectsRequest.builder();
 
   @Test
   public void verify_definition() {
@@ -1111,7 +1112,7 @@ public class SearchProjectsActionTest {
     call(request.setPageSize(501));
   }
 
-  private SearchProjectsWsResponse call(SearchProjectsRequest.Builder requestBuilder) {
+  private SearchProjectsWsResponse call(RequestBuilder requestBuilder) {
     SearchProjectsRequest wsRequest = requestBuilder.build();
     TestRequest httpRequest = ws.newRequest();
     ofNullable(wsRequest.getOrganization()).ifPresent(organization -> httpRequest.setParam(PARAM_ORGANIZATION, organization));
index 9ac942c58b5536c0b0cb45abdd20c7723904740c..bae47d6a5e9e9d50a7c30564e11c9e6f032ce555 100644 (file)
@@ -35,7 +35,6 @@ import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.tester.UserSessionRule;
-import org.sonarqube.ws.client.issue.SearchRequest;
 
 import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
index a88c1f70004eee4f5116a6689be2a80de6c1d1b3..dfb147d37285398b39cd74b8913d966c11b41ef1 100644 (file)
@@ -25,6 +25,7 @@ import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
+import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.junit.Before;
 import org.junit.Rule;
@@ -67,10 +68,12 @@ import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.WsActionTester;
 import org.sonarqube.ws.Issues.BulkChangeWsResponse;
-import org.sonarqube.ws.client.issue.BulkChangeRequest;
 
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.Lists.newArrayList;
 import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
+import static java.util.Objects.requireNonNull;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.tuple;
 import static org.mockito.Matchers.eq;
@@ -145,7 +148,7 @@ public class BulkChangeActionTest {
     setUserProjectPermissions(USER, ISSUE_ADMIN);
     IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue().setType(BUG));
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(singletonList(issueDto.getKey()))
       .setSetType(RuleType.CODE_SMELL.name())
       .build());
@@ -163,7 +166,7 @@ public class BulkChangeActionTest {
     setUserProjectPermissions(USER, ISSUE_ADMIN);
     IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue().setSeverity(MAJOR));
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(singletonList(issueDto.getKey()))
       .setSetSeverity(MINOR)
       .build());
@@ -181,7 +184,7 @@ public class BulkChangeActionTest {
     setUserProjectPermissions(USER, ISSUE_ADMIN);
     IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue().setTags(asList("tag1", "tag2")));
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(singletonList(issueDto.getKey()))
       .setAddTags(singletonList("tag3"))
       .build());
@@ -199,7 +202,7 @@ public class BulkChangeActionTest {
     setUserProjectPermissions(USER);
     IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue().setAssignee("arthur"));
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(singletonList(issueDto.getKey()))
       .setAssign("")
       .build());
@@ -217,7 +220,7 @@ public class BulkChangeActionTest {
     setUserProjectPermissions(USER);
     IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue().setType(BUG));
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(singletonList(issueDto.getKey()))
       .setDoTransition("confirm")
       .setComment("type was badly defined")
@@ -241,7 +244,7 @@ public class BulkChangeActionTest {
     IssueDto issue2 = db.issues().insertIssue(newUnresolvedIssue().setAssignee(userToAssign.getLogin())).setType(BUG).setSeverity(MAJOR);
     IssueDto issue3 = db.issues().insertIssue(newUnresolvedIssue().setAssignee(null)).setType(VULNERABILITY).setSeverity(MAJOR);
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(asList(issue1.getKey(), issue2.getKey(), issue3.getKey()))
       .setAssign(userToAssign.getLogin())
       .setSetSeverity(MINOR)
@@ -264,7 +267,7 @@ public class BulkChangeActionTest {
     setUserProjectPermissions(USER);
     IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue().setType(BUG));
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(singletonList(issueDto.getKey()))
       .setDoTransition("confirm")
       .setSendNotifications(true)
@@ -294,7 +297,7 @@ public class BulkChangeActionTest {
     ComponentDto fileOnBranch = db.components().insertComponent(newFileDto(branch));
     IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue(rule, fileOnBranch, branch).setType(BUG));
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(singletonList(issueDto.getKey()))
       .setDoTransition("confirm")
       .setSendNotifications(true)
@@ -323,7 +326,7 @@ public class BulkChangeActionTest {
     IssueDto issue3 = db.issues().insertIssue(newUnresolvedIssue().setType(VULNERABILITY));
     ArgumentCaptor<IssueChangeNotification> issueChangeNotificationCaptor = ArgumentCaptor.forClass(IssueChangeNotification.class);
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(asList(issue1.getKey(), issue2.getKey(), issue3.getKey()))
       .setSetType(RuleType.BUG.name())
       .setSendNotifications(true)
@@ -345,7 +348,7 @@ public class BulkChangeActionTest {
     IssueDto issue2 = db.issues().insertIssue(newResolvedIssue().setType(BUG));
     IssueDto issue3 = db.issues().insertIssue(newResolvedIssue().setType(BUG));
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(asList(issue1.getKey(), issue2.getKey(), issue3.getKey()))
       .setSetType(VULNERABILITY.name())
       .build());
@@ -369,7 +372,7 @@ public class BulkChangeActionTest {
     IssueDto issue2 = db.issues().insertIssue(newUnresolvedIssue().setType(VULNERABILITY));
     IssueDto issue3 = db.issues().insertIssue(newUnresolvedIssue().setType(VULNERABILITY));
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(asList(issue1.getKey(), issue2.getKey(), issue3.getKey()))
       .setSetType(VULNERABILITY.name())
       .build());
@@ -393,7 +396,7 @@ public class BulkChangeActionTest {
     IssueDto issue2 = db.issues().insertIssue(newUnresolvedIssue().setType(VULNERABILITY));
     IssueDto issue3 = db.issues().insertIssue(newUnresolvedIssue().setType(VULNERABILITY));
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(asList(issue1.getKey(), issue2.getKey(), issue3.getKey()))
       .setSetType(VULNERABILITY.name())
       .setComment("test")
@@ -417,7 +420,7 @@ public class BulkChangeActionTest {
     IssueDto notAuthorizedIssue1 = db.issues().insertIssue(newUnresolvedIssue(rule, anotherFile, anotherProject).setType(BUG));
     IssueDto notAuthorizedIssue2 = db.issues().insertIssue(newUnresolvedIssue(rule, anotherFile, anotherProject).setType(BUG));
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(asList(authorizedIssue.getKey(), notAuthorizedIssue1.getKey(), notAuthorizedIssue2.getKey()))
       .setSetType(VULNERABILITY.name())
       .build());
@@ -445,7 +448,7 @@ public class BulkChangeActionTest {
     IssueDto notAuthorizedIssue1 = db.issues().insertIssue(newUnresolvedIssue(rule, anotherFile, anotherProject).setType(BUG));
     IssueDto notAuthorizedIssue2 = db.issues().insertIssue(newUnresolvedIssue(rule, anotherFile, anotherProject).setType(BUG));
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(asList(authorizedIssue1.getKey(), notAuthorizedIssue1.getKey(), notAuthorizedIssue2.getKey()))
       .setSetType(VULNERABILITY.name())
       .build());
@@ -471,7 +474,7 @@ public class BulkChangeActionTest {
     IssueDto notAuthorizedIssue1 = db.issues().insertIssue(newUnresolvedIssue(rule, anotherFile, anotherProject).setSeverity(MAJOR));
     IssueDto notAuthorizedIssue2 = db.issues().insertIssue(newUnresolvedIssue(rule, anotherFile, anotherProject).setSeverity(MAJOR));
 
-    BulkChangeWsResponse response = call(BulkChangeRequest.builder()
+    BulkChangeWsResponse response = call(builder()
       .setIssues(asList(authorizedIssue1.getKey(), notAuthorizedIssue1.getKey(), notAuthorizedIssue2.getKey()))
       .setSetSeverity(MINOR)
       .build());
@@ -492,7 +495,7 @@ public class BulkChangeActionTest {
     expectedException.expectMessage("At least one action must be provided");
     expectedException.expect(IllegalArgumentException.class);
 
-    call(BulkChangeRequest.builder()
+    call(builder()
       .setIssues(singletonList(issueDto.getKey()))
       .setComment("type was badly defined")
       .build());
@@ -504,7 +507,7 @@ public class BulkChangeActionTest {
     expectedException.expectMessage("Number of issues is limited to 500");
     expectedException.expect(IllegalArgumentException.class);
 
-    call(BulkChangeRequest.builder()
+    call(builder()
       .setIssues(IntStream.range(0, 510).mapToObj(String::valueOf).collect(Collectors.toList()))
       .setSetSeverity(MINOR)
       .build());
@@ -514,7 +517,7 @@ public class BulkChangeActionTest {
   public void fail_when_not_authenticated() throws Exception {
     expectedException.expect(UnauthorizedException.class);
 
-    call(BulkChangeRequest.builder().setIssues(singletonList("ABCD")).build());
+    call(builder().setIssues(singletonList("ABCD")).build());
   }
 
   @Test
@@ -607,4 +610,137 @@ public class BulkChangeActionTest {
     actions.add(new org.sonar.server.issue.CommentAction(issueFieldsSetter));
   }
 
+  private static class BulkChangeRequest {
+
+    private final List<String> issues;
+    private final String assign;
+    private final String setSeverity;
+    private final String setType;
+    private final String doTransition;
+    private final List<String> addTags;
+    private final List<String> removeTags;
+    private final String comment;
+    private final Boolean sendNotifications;
+
+    private BulkChangeRequest(Builder builder) {
+      this.issues = builder.issues;
+      this.assign = builder.assign;
+      this.setSeverity = builder.setSeverity;
+      this.setType = builder.setType;
+      this.doTransition = builder.doTransition;
+      this.addTags = builder.addTags;
+      this.removeTags = builder.removeTags;
+      this.comment = builder.comment;
+      this.sendNotifications = builder.sendNotifications;
+    }
+
+    public List<String> getIssues() {
+      return issues;
+    }
+
+    @CheckForNull
+    public String getAssign() {
+      return assign;
+    }
+
+    @CheckForNull
+    public String getSetSeverity() {
+      return setSeverity;
+    }
+
+    @CheckForNull
+    public String getSetType() {
+      return setType;
+    }
+
+    @CheckForNull
+    public String getDoTransition() {
+      return doTransition;
+    }
+
+    public List<String> getAddTags() {
+      return addTags;
+    }
+
+    public List<String> getRemoveTags() {
+      return removeTags;
+    }
+
+    @CheckForNull
+    public String getComment() {
+      return comment;
+    }
+
+    @CheckForNull
+    public Boolean getSendNotifications() {
+      return sendNotifications;
+    }
+
+  }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  public static class Builder {
+    private List<String> issues;
+    private String assign;
+    private String setSeverity;
+    private String setType;
+    private String doTransition;
+    private List<String> addTags = newArrayList();
+    private List<String> removeTags = newArrayList();
+    private String comment;
+    private Boolean sendNotifications;
+
+    public Builder setIssues(List<String> issues) {
+      this.issues = issues;
+      return this;
+    }
+
+    public Builder setAssign(@Nullable String assign) {
+      this.assign = assign;
+      return this;
+    }
+
+    public Builder setSetSeverity(@Nullable String setSeverity) {
+      this.setSeverity = setSeverity;
+      return this;
+    }
+
+    public Builder setSetType(@Nullable String setType) {
+      this.setType = setType;
+      return this;
+    }
+
+    public Builder setDoTransition(@Nullable String doTransition) {
+      this.doTransition = doTransition;
+      return this;
+    }
+
+    public Builder setAddTags(List<String> addTags) {
+      this.addTags = requireNonNull(addTags);
+      return this;
+    }
+
+    public Builder setRemoveTags(List<String> removeTags) {
+      this.removeTags = requireNonNull(removeTags);
+      return this;
+    }
+
+    public Builder setComment(@Nullable String comment) {
+      this.comment = comment;
+      return this;
+    }
+
+    public Builder setSendNotifications(@Nullable Boolean sendNotifications) {
+      this.sendNotifications = sendNotifications;
+      return this;
+    }
+
+    public BulkChangeRequest build() {
+      checkArgument(issues != null && !issues.isEmpty(), "Issue keys must be provided");
+      return new BulkChangeRequest(this);
+    }
+  }
 }
index b020c4426fcd9e24d4c998d36e57c8f6dff563b8..23261f4ee3fb30d446701dc8e7bb9bc0d784528a 100644 (file)
@@ -31,7 +31,7 @@ import org.sonar.server.issue.IssueQueryFactory;
 import org.sonar.server.issue.index.IssueIndex;
 import org.sonar.server.ws.TestResponse;
 import org.sonar.server.ws.WsActionTester;
-import org.sonarqube.ws.client.issue.SearchRequest;
+import org.sonar.server.issue.SearchRequest;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Matchers.any;
index 32bc30d6a3173634253fb4e0e39049ef3787c85a..c5ab5886cdab6c97fb7851d33382c02123be27f0 100644 (file)
@@ -112,7 +112,7 @@ public class ComponentTreeActionTest {
 
   private WsActionTester ws = new WsActionTester(
     new ComponentTreeAction(
-      new ComponentTreeDataLoader(dbClient, new ComponentFinder(dbClient, resourceTypes), userSession, resourceTypes),
+      dbClient, new ComponentFinder(dbClient, resourceTypes), userSession,
       i18n, resourceTypes));
 
   @Test
index 379f774723772d0b637236cffc84a35631be5a8c..839a9c05864bb902a197b393e481a8823ade5bb8 100644 (file)
@@ -32,7 +32,6 @@ import org.sonar.core.util.Uuids;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.measure.MeasureDto;
 import org.sonar.db.metric.MetricDto;
-import org.sonarqube.ws.client.measure.ComponentTreeRequest;
 
 import static com.google.common.collect.Lists.newArrayList;
 import static java.util.Collections.singletonList;
index 9f0343ecdfee095054f85c249b6a0701f8122100..33f45d2f2abb6a36841d5de94e0deaccef22ab5e 100644 (file)
@@ -29,6 +29,6 @@ public class MeasuresWsModuleTest {
   public void verify_count_of_added_components() {
     ComponentContainer container = new ComponentContainer();
     new MeasuresWsModule().configure(container);
-    assertThat(container.size()).isEqualTo(6 + 2);
+    assertThat(container.size()).isEqualTo(5 + 2);
   }
 }
index a649929c8d4708c0ffcd2d93cb45602c9cd936d2..7c6913c2ec329ff97250ed08d42acb5a441b21aa 100644 (file)
@@ -31,7 +31,7 @@ import org.sonar.server.ws.WsTester;
 public class MeasuresWsTest {
   WsTester ws = new WsTester(
     new MeasuresWs(
-      new ComponentTreeAction(mock(ComponentTreeDataLoader.class), mock(I18n.class), mock(ResourceTypes.class))));
+      new ComponentAction(null, null, null)));
 
   @Test
   public void define_ws() {
index 73ae00a32b77fb426c4fc3630b6412dfd697d105..f778f3fdac04ae681e5159873bec0c7349e2eec2 100644 (file)
@@ -43,6 +43,8 @@ import org.sonar.db.organization.OrganizationDto;
 import org.sonar.server.component.TestComponentFinder;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.measure.ws.SearchHistoryAction.Builder;
+import org.sonar.server.measure.ws.SearchHistoryAction.SearchHistoryRequest;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.WsActionTester;
@@ -50,7 +52,6 @@ import org.sonarqube.ws.Common.Paging;
 import org.sonarqube.ws.Measures.SearchHistoryResponse;
 import org.sonarqube.ws.Measures.SearchHistoryResponse.HistoryMeasure;
 import org.sonarqube.ws.Measures.SearchHistoryResponse.HistoryValue;
-import org.sonarqube.ws.client.measure.SearchHistoryRequest;
 
 import static com.google.common.collect.Lists.newArrayList;
 import static java.lang.Double.parseDouble;
@@ -94,7 +95,7 @@ public class SearchHistoryActionTest {
   private MetricDto complexityMetric;
   private MetricDto nclocMetric;
   private MetricDto newViolationMetric;
-  private SearchHistoryRequest.Builder wsRequest;
+  private Builder wsRequest;
 
   @Before
   public void setUp() {
index 95558a89bcb15b75160bb2ebd52495747f6d635c..26314b1c9c69ee0010e2d57d0ad51ad178b83c23 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.server.notification.ws;
 
+import javax.annotation.Nullable;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -42,7 +43,6 @@ import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.TestResponse;
 import org.sonar.server.ws.WsActionTester;
-import org.sonarqube.ws.client.notifications.AddRequest;
 
 import static java.lang.String.format;
 import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
@@ -82,8 +82,6 @@ public class AddActionTest {
   private AddAction underTest;
   private WsActionTester ws;
 
-  private AddRequest request = new AddRequest().setType(NOTIF_MY_NEW_ISSUES);
-
   @Before
   public void setUp() {
     NotificationDispatcherMetadata metadata1 = NotificationDispatcherMetadata.create(NOTIF_MY_NEW_ISSUES)
@@ -107,14 +105,14 @@ public class AddActionTest {
 
   @Test
   public void add_to_email_channel_by_default() {
-    call(request);
+    call(NOTIF_MY_NEW_ISSUES, null, null, null);
 
     db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), null);
   }
 
   @Test
   public void add_to_a_specific_channel() {
-    call(request.setType(NOTIF_NEW_QUALITY_GATE_STATUS).setChannel(twitterChannel.getKey()));
+    call(NOTIF_NEW_QUALITY_GATE_STATUS, twitterChannel.getKey(), null, null);
 
     db.notifications().assertExists(twitterChannel.getKey(), NOTIF_NEW_QUALITY_GATE_STATUS, userSession.getUserId(), null);
   }
@@ -124,7 +122,7 @@ public class AddActionTest {
     ComponentDto project = db.components().insertPrivateProject();
     userSession.addProjectPermission(UserRole.USER, project);
 
-    call(request.setProject(project.getDbKey()));
+    call(NOTIF_MY_NEW_ISSUES, null, project.getDbKey(), null);
 
     db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project);
   }
@@ -133,7 +131,7 @@ public class AddActionTest {
   public void add_notification_on_public_project() {
     ComponentDto project = db.components().insertPublicProject();
     userSession.registerComponents(project);
-    call(request.setProject(project.getDbKey()));
+    call(NOTIF_MY_NEW_ISSUES, null, project.getDbKey(), null);
 
     db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project);
   }
@@ -142,9 +140,9 @@ public class AddActionTest {
   public void add_a_global_notification_when_a_project_one_exists() {
     ComponentDto project = db.components().insertPrivateProject();
     userSession.addProjectPermission(UserRole.USER, project);
-    call(request.setProject(project.getDbKey()));
+    call(NOTIF_MY_NEW_ISSUES, null, project.getDbKey(), null);
 
-    call(request.setProject(null));
+    call(NOTIF_MY_NEW_ISSUES, null, null, null);
 
     db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project);
     db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), null);
@@ -153,10 +151,10 @@ public class AddActionTest {
   @Test
   public void add_a_notification_on_private_project_when_a_global_one_exists() {
     ComponentDto project = db.components().insertPrivateProject();
-    call(request);
+    call(NOTIF_MY_NEW_ISSUES, null, null, null);
 
     userSession.addProjectPermission(UserRole.USER, project);
-    call(request.setProject(project.getDbKey()));
+    call(NOTIF_MY_NEW_ISSUES, null, project.getDbKey(), null);
 
     db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project);
     db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), null);
@@ -167,9 +165,9 @@ public class AddActionTest {
   public void add_a_notification_on_public_project_when_a_global_one_exists() {
     ComponentDto project = db.components().insertPublicProject();
     userSession.registerComponents(project);
-    call(request);
+    call(NOTIF_MY_NEW_ISSUES, null, null, null);
 
-    call(request.setProject(project.getDbKey()));
+    call(NOTIF_MY_NEW_ISSUES, null, project.getDbKey(), null);
 
     db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project);
     db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), null);
@@ -177,7 +175,7 @@ public class AddActionTest {
 
   @Test
   public void http_no_content() {
-    TestResponse result = call(request);
+    TestResponse result = call(NOTIF_MY_NEW_ISSUES, null, null, null);
 
     assertThat(result.getStatus()).isEqualTo(HTTP_NO_CONTENT);
   }
@@ -186,7 +184,7 @@ public class AddActionTest {
   public void add_a_notification_to_a_user_as_system_administrator() {
     userSession.logIn().setSystemAdministrator();
 
-    call(request.setLogin(user.getLogin()));
+    call(NOTIF_MY_NEW_ISSUES, null, null, user.getLogin());
 
     db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user.getId(), null);
   }
@@ -198,7 +196,7 @@ public class AddActionTest {
     expectedException.expect(NotFoundException.class);
     expectedException.expectMessage("User 'LOGIN 404' not found");
 
-    call(request.setLogin("LOGIN 404"));
+    call(NOTIF_MY_NEW_ISSUES, null, null, "LOGIN 404");
   }
 
   @Test
@@ -207,24 +205,24 @@ public class AddActionTest {
 
     expectedException.expect(ForbiddenException.class);
 
-    call(request.setLogin(user.getLogin()));
+    call(NOTIF_MY_NEW_ISSUES, null, null, user.getLogin());
   }
 
   @Test
   public void fail_when_notification_already_exists() {
-    call(request);
+    call(NOTIF_MY_NEW_ISSUES, null, null, null);
 
     expectedException.expect(IllegalArgumentException.class);
     expectedException.expectMessage("Notification already added");
 
-    call(request);
+    call(NOTIF_MY_NEW_ISSUES, null, null, null);
   }
 
   @Test
   public void fail_when_unknown_channel() {
     expectedException.expect(IllegalArgumentException.class);
 
-    call(request.setChannel("Channel42"));
+    call(NOTIF_MY_NEW_ISSUES, "Channel42", null, null);
   }
 
   @Test
@@ -232,7 +230,7 @@ public class AddActionTest {
     expectedException.expect(BadRequestException.class);
     expectedException.expectMessage("Value of parameter 'type' (Dispatcher42) must be one of: [Dispatcher1, Dispatcher2, Dispatcher3]");
 
-    call(request.setType("Dispatcher42"));
+    call("Dispatcher42", null, null, null);
   }
 
   @Test
@@ -243,7 +241,7 @@ public class AddActionTest {
     expectedException.expect(BadRequestException.class);
     expectedException.expectMessage("Value of parameter 'type' (Dispatcher42) must be one of: [Dispatcher1, Dispatcher3]");
 
-    call(request.setType("Dispatcher42").setProject(project.getDbKey()));
+    call("Dispatcher42", null, project.getDbKey(), null);
   }
 
   @Test
@@ -253,7 +251,7 @@ public class AddActionTest {
     expectedException.expect(BadRequestException.class);
     expectedException.expectMessage("Value of parameter 'type' (Dispatcher42) must be one of: [Dispatcher1, Dispatcher3]");
 
-    call(request.setType("Dispatcher42").setProject(project.getDbKey()));
+    call("Dispatcher42", null, project.getDbKey(), null);
   }
 
   @Test
@@ -267,7 +265,7 @@ public class AddActionTest {
   public void fail_when_project_is_unknown() {
     expectedException.expect(NotFoundException.class);
 
-    call(request.setProject("Project-42"));
+    call(NOTIF_MY_NEW_ISSUES, null, "Project-42", null);
   }
 
   @Test
@@ -277,7 +275,7 @@ public class AddActionTest {
     expectedException.expect(BadRequestException.class);
     expectedException.expectMessage("Component 'VIEW_1' must be a project");
 
-    call(request.setProject("VIEW_1"));
+    call(NOTIF_MY_NEW_ISSUES, null, "VIEW_1", null);
   }
 
   @Test
@@ -286,7 +284,7 @@ public class AddActionTest {
 
     expectedException.expect(UnauthorizedException.class);
 
-    call(request);
+    call(NOTIF_MY_NEW_ISSUES, null, null, null);
   }
 
   @Test
@@ -297,7 +295,7 @@ public class AddActionTest {
     expectedException.expect(NotFoundException.class);
     expectedException.expectMessage(format("Component key '%s' not found", branch.getDbKey()));
 
-    call(request.setProject(branch.getDbKey()));
+    call(NOTIF_MY_NEW_ISSUES, null, branch.getDbKey(), null);
   }
 
   @Test
@@ -307,17 +305,15 @@ public class AddActionTest {
 
     expectedException.expect(ForbiddenException.class);
 
-    call(request
-      .setProject(project.getDbKey())
-      .setLogin(userSession.getLogin()));
+    call(NOTIF_MY_NEW_ISSUES, null, project.getDbKey(), userSession.getLogin());
   }
 
-  private TestResponse call(AddRequest add) {
+  private TestResponse call(String type, @Nullable String channel, @Nullable String project, @Nullable String login) {
     TestRequest request = ws.newRequest();
-    request.setParam(PARAM_TYPE, add.getType());
-    setNullable(add.getChannel(), channel -> request.setParam(PARAM_CHANNEL, channel));
-    setNullable(add.getProject(), project -> request.setParam(PARAM_PROJECT, project));
-    setNullable(add.getLogin(), login -> request.setParam(PARAM_LOGIN, login));
+    request.setParam(PARAM_TYPE, type);
+    setNullable(channel, channel1 -> request.setParam(PARAM_CHANNEL, channel1));
+    setNullable(project, project1 -> request.setParam(PARAM_PROJECT, project1));
+    setNullable(login, login1 -> request.setParam(PARAM_LOGIN, login1));
     return request.execute();
   }
 
index 2b9750759802fba04cb2ef055b9d3cd2510951a9..7289356e956b9d8ef9f4f9de6f5662808ecf6651 100644 (file)
@@ -38,11 +38,11 @@ import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.notification.NotificationCenter;
 import org.sonar.server.notification.NotificationDispatcherMetadata;
 import org.sonar.server.notification.NotificationUpdater;
+import org.sonar.server.notification.ws.RemoveAction.RemoveRequest;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.TestResponse;
 import org.sonar.server.ws.WsActionTester;
-import org.sonarqube.ws.client.notifications.RemoveRequest;
 
 import static java.lang.String.format;
 import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
index 695869c6d48fc00dcfb8c4f5ec99dc90d7563bdd..51c8ccd02091d4b1df7c9d7a84d2538f43b5ccab 100644 (file)
@@ -21,6 +21,8 @@
 package org.sonar.server.organization.ws;
 
 import java.util.stream.IntStream;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -48,7 +50,6 @@ import org.sonar.server.ws.WsActionTester;
 import org.sonarqube.ws.Common.Paging;
 import org.sonarqube.ws.Organizations.SearchMembersWsResponse;
 import org.sonarqube.ws.Organizations.User;
-import org.sonarqube.ws.client.organization.SearchMembersRequest;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.tuple;
@@ -329,4 +330,62 @@ public class SearchMembersActionTest {
 
     return wsRequest.executeProtobuf(SearchMembersWsResponse.class);
   }
+
+  private static class SearchMembersRequest {
+    private String organization;
+    private String selected;
+    private String query;
+    private Integer page;
+    private Integer pageSize;
+
+    @CheckForNull
+    public String getOrganization() {
+      return organization;
+    }
+
+    public SearchMembersRequest setOrganization(@Nullable String organization) {
+      this.organization = organization;
+      return this;
+    }
+
+    @CheckForNull
+    public String getSelected() {
+      return selected;
+    }
+
+    public SearchMembersRequest setSelected(@Nullable String selected) {
+      this.selected = selected;
+      return this;
+    }
+
+    @CheckForNull
+    public String getQuery() {
+      return query;
+    }
+
+    public SearchMembersRequest setQuery(@Nullable String query) {
+      this.query = query;
+      return this;
+    }
+
+    @CheckForNull
+    public Integer getPage() {
+      return page;
+    }
+
+    public SearchMembersRequest setPage(@Nullable Integer page) {
+      this.page = page;
+      return this;
+    }
+
+    @CheckForNull
+    public Integer getPageSize() {
+      return pageSize;
+    }
+
+    public SearchMembersRequest setPageSize(@Nullable Integer pageSize) {
+      this.pageSize = pageSize;
+      return this;
+    }
+  }
 }
index 83fa929ce579eaccdf8edfdaa0338f989cf69163..f409cfcc7bb2e7f2c8385e726dbe813405b1b718 100644 (file)
@@ -30,6 +30,6 @@ public class PermissionsWsModuleTest {
   public void verify_count_of_added_components() {
     ComponentContainer container = new ComponentContainer();
     new PermissionsWsModule().configure(container);
-    assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 27);
+    assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 25);
   }
 }
index 58605ca8d2419f8c689e6860be7cffaf962eb8b7..894a575adad253e95be4b899438224f8d38f4b7a 100644 (file)
@@ -66,8 +66,7 @@ public class SearchProjectPermissionsActionTest extends BasePermissionWsTest<Sea
     i18n.setProjectPermissions();
     ResourceTypesRule rootResourceTypes = newRootResourceTypes();
     PermissionWsSupport wsSupport = newPermissionWsSupport();
-    SearchProjectPermissionsDataLoader dataLoader = new SearchProjectPermissionsDataLoader(db.getDbClient(), wsSupport, rootResourceTypes);
-    return new SearchProjectPermissionsAction(db.getDbClient(), userSession, i18n, rootResourceTypes, dataLoader, wsSupport);
+    return new SearchProjectPermissionsAction(db.getDbClient(), userSession, i18n, rootResourceTypes, wsSupport);
   }
 
   @Test
index df52f34b91012f6cca1002f5c03d7bde302a64ee..f2d3cc2eea03b839a400cb3ab01be1fd7806b72e 100644 (file)
@@ -61,16 +61,14 @@ public class SearchTemplatesActionTest extends BasePermissionWsTest<SearchTempla
   @Override
   protected SearchTemplatesAction buildWsAction() {
     DefaultTemplatesResolver defaultTemplatesResolverWithViews = new DefaultTemplatesResolverImpl(resourceTypesWithViews);
-    SearchTemplatesDataLoader dataLoaderWithViews = new SearchTemplatesDataLoader(dbClient, defaultTemplatesResolverWithViews);
-    SearchTemplatesAction searchTemplatesAction = new SearchTemplatesAction(dbClient, userSession, i18n, newPermissionWsSupport(), dataLoaderWithViews);
+    SearchTemplatesAction searchTemplatesAction = new SearchTemplatesAction(dbClient, userSession, i18n, newPermissionWsSupport(), defaultTemplatesResolverWithViews);
     return searchTemplatesAction;
   }
 
   @Before
   public void setUp() {
     DefaultTemplatesResolver defaultTemplatesResolverWithViews = new DefaultTemplatesResolverImpl(resourceTypesWithoutViews);
-    SearchTemplatesDataLoader dataLoaderWithViews = new SearchTemplatesDataLoader(dbClient, defaultTemplatesResolverWithViews);
-    underTestWithoutViews = new WsActionTester(new SearchTemplatesAction(dbClient, userSession, i18n, newPermissionWsSupport(), dataLoaderWithViews));
+    underTestWithoutViews = new WsActionTester(new SearchTemplatesAction(dbClient, userSession, i18n, newPermissionWsSupport(), defaultTemplatesResolverWithViews));
     i18n.setProjectPermissions();
     userSession.logIn().addPermission(ADMINISTER, db.getDefaultOrganization());
   }
index f6039570f0d5676c5f744fade2bfadc8afed8d68..278466906bc751535bc63588ec9cb2ac1c4ecab1 100644 (file)
@@ -40,12 +40,12 @@ import org.sonar.server.organization.BillingValidationsProxy;
 import org.sonar.server.organization.DefaultOrganizationProvider;
 import org.sonar.server.organization.TestDefaultOrganizationProvider;
 import org.sonar.server.permission.PermissionTemplateService;
+import org.sonar.server.project.ws.CreateAction.CreateRequest;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.WsActionTester;
 import org.sonarqube.ws.Projects.CreateWsResponse;
 import org.sonarqube.ws.Projects.CreateWsResponse.Project;
-import org.sonarqube.ws.client.project.CreateRequest;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Matchers.any;
index dd594cda0990cdf22804feebaa47833c5ba46223..1a8b29a0624a92137f76156da656c9cbfefb8fac 100644 (file)
@@ -30,6 +30,6 @@ public class ProjectsWsModuleTest {
   public void verify_count_of_added_components() {
     ComponentContainer container = new ComponentContainer();
     new ProjectsWsModule().configure(container);
-    assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 14);
+    assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 13);
   }
 }
index 0c74c2cca219095fcea707095708152b1bc20c95..1b581ca635172bf0e6a273f6f6b0813088a81426 100644 (file)
@@ -48,7 +48,6 @@ import org.sonarqube.ws.MediaTypes;
 import org.sonarqube.ws.Projects.SearchWsResponse;
 import org.sonarqube.ws.Projects.SearchWsResponse.Component;
 import org.sonarqube.ws.client.component.ComponentsWsParameters;
-import org.sonarqube.ws.client.project.SearchRequest;
 
 import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
index fb7574edbfc8c30ab0fb656fa6bd2b479c130d1d..d0d986e8b0e37e9d04f0c0caa57919f86bca2f23 100644 (file)
@@ -79,7 +79,7 @@ public class SearchMyProjectsActionTest {
     alertStatusMetric = dbClient.metricDao().insert(dbSession, newMetricDto().setKey(ALERT_STATUS_KEY).setValueType(ValueType.LEVEL.name()));
     db.commit();
 
-    ws = new WsActionTester(new SearchMyProjectsAction(dbClient, new SearchMyProjectsDataLoader(userSession, dbClient), userSession));
+    ws = new WsActionTester(new SearchMyProjectsAction(dbClient, userSession));
   }
 
   @Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/SearchMyProjectsDataLoaderTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/SearchMyProjectsDataLoaderTest.java
deleted file mode 100644 (file)
index cd34521..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.project.ws;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonarqube.ws.client.project.SearchMyProjectsRequest;
-
-import static org.mockito.Mockito.mock;
-
-public class SearchMyProjectsDataLoaderTest {
-
-  @Rule
-  public ExpectedException expectedException = ExpectedException.none();
-  @Rule
-  public UserSessionRule userSession = UserSessionRule.standalone();
-
-  SearchMyProjectsDataLoader underTest = new SearchMyProjectsDataLoader(userSession, mock(DbClient.class));
-
-  @Test
-  public void NPE_when_user_is_not_authenticated() {
-    expectedException.expect(NullPointerException.class);
-    expectedException.expectMessage("Current user must be authenticated");
-
-    userSession.anonymous();
-
-    underTest.searchProjects(mock(DbSession.class), mock(SearchMyProjectsRequest.class));
-  }
-}
index 2af76f40f032b02dd54e30c02fa4e92157aa3f6a..5b536ebcf36e1a08d568ea7b5f95d29670188bde 100644 (file)
@@ -45,7 +45,6 @@ import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.WsActionTester;
 import org.sonarqube.ws.ProjectAnalyses;
 import org.sonarqube.ws.ProjectAnalyses.CreateEventResponse;
-import org.sonarqube.ws.client.projectanalysis.CreateEventRequest;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -107,14 +106,10 @@ public class CreateEventActionTest {
   public void create_event_in_db() {
     ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
     SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
-    CreateEventRequest.Builder request = CreateEventRequest.builder()
-      .setAnalysis(analysis.getUuid())
-      .setCategory(VERSION)
-      .setName("5.6.3");
     when(system.now()).thenReturn(123_456_789L);
     logInAsProjectAdministrator(project);
 
-    CreateEventResponse result = call(request);
+    CreateEventResponse result = call(VERSION.name(), "5.6.3", analysis.getUuid());
 
     List<EventDto> dbEvents = dbClient.eventDao().selectByComponentUuid(dbSession, analysis.getComponentUuid());
     assertThat(dbEvents).hasSize(1);
@@ -133,13 +128,9 @@ public class CreateEventActionTest {
   public void create_event_as_project_admin() {
     ComponentDto project = newPrivateProjectDto(db.getDefaultOrganization(), "P1");
     SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
-    CreateEventRequest.Builder request = CreateEventRequest.builder()
-      .setAnalysis(analysis.getUuid())
-      .setCategory(VERSION)
-      .setName("5.6.3");
     logInAsProjectAdministrator(project);
 
-    CreateEventResponse result = call(request);
+    CreateEventResponse result = call(VERSION.name(), "5.6.3", analysis.getUuid());
 
     assertThat(result.getEvent().getKey()).isNotEmpty();
   }
@@ -148,13 +139,9 @@ public class CreateEventActionTest {
   public void create_version_event() {
     ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
     SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
-    CreateEventRequest.Builder request = CreateEventRequest.builder()
-      .setAnalysis(analysis.getUuid())
-      .setCategory(VERSION)
-      .setName("5.6.3");
     logInAsProjectAdministrator(project);
 
-    call(request);
+    call(VERSION.name(), "5.6.3", analysis.getUuid());
 
     Optional<SnapshotDto> newAnalysis = dbClient.snapshotDao().selectByUuid(dbSession, analysis.getUuid());
     assertThat(newAnalysis.get().getVersion()).isEqualTo("5.6.3");
@@ -164,12 +151,9 @@ public class CreateEventActionTest {
   public void create_other_event_with_ws_response() {
     ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
     SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
-    CreateEventRequest.Builder request = CreateEventRequest.builder()
-      .setAnalysis(analysis.getUuid())
-      .setName("Project Import");
     logInAsProjectAdministrator(project);
 
-    CreateEventResponse result = call(request);
+    CreateEventResponse result = call(OTHER.name(), "Project Import", analysis.getUuid());
 
     SnapshotDto newAnalysis = dbClient.snapshotDao().selectByUuid(dbSession, analysis.getUuid()).get();
     assertThat(analysis.getVersion()).isEqualTo(newAnalysis.getVersion());
@@ -185,13 +169,9 @@ public class CreateEventActionTest {
   public void create_event_without_description() {
     ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
     SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
-    CreateEventRequest.Builder request = CreateEventRequest.builder()
-      .setAnalysis(analysis.getUuid())
-      .setCategory(OTHER)
-      .setName("Project Import");
     logInAsProjectAdministrator(project);
 
-    CreateEventResponse result = call(request);
+    CreateEventResponse result = call(OTHER.name(), "Project Import", analysis.getUuid());
 
     ProjectAnalyses.Event event = result.getEvent();
     assertThat(event.getKey()).isNotEmpty();
@@ -202,13 +182,9 @@ public class CreateEventActionTest {
   public void create_event_on_application() {
     ComponentDto application = ComponentTesting.newApplication(db.getDefaultOrganization());
     SnapshotDto analysis = db.components().insertProjectAndSnapshot(application);
-    CreateEventRequest.Builder request = CreateEventRequest.builder()
-      .setAnalysis(analysis.getUuid())
-      .setCategory(OTHER)
-      .setName("Application Event");
     logInAsProjectAdministrator(application);
 
-    CreateEventResponse result = call(request);
+    CreateEventResponse result = call(OTHER.name(), "Application Event", analysis.getUuid());
 
     ProjectAnalyses.Event event = result.getEvent();
     assertThat(event.getName()).isEqualTo("Application Event");
@@ -218,20 +194,12 @@ public class CreateEventActionTest {
   public void create_2_version_events_on_same_project() {
     ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
     SnapshotDto firstAnalysis = db.components().insertProjectAndSnapshot(project);
-    CreateEventRequest.Builder firstRequest = CreateEventRequest.builder()
-      .setAnalysis(firstAnalysis.getUuid())
-      .setCategory(VERSION)
-      .setName("5.6.3");
     SnapshotDto secondAnalysis = dbClient.snapshotDao().insert(dbSession, newAnalysis(project));
     db.commit();
-    CreateEventRequest.Builder secondRequest = CreateEventRequest.builder()
-      .setAnalysis(secondAnalysis.getUuid())
-      .setCategory(VERSION)
-      .setName("6.3");
     logInAsProjectAdministrator(project);
 
-    call(firstRequest);
-    call(secondRequest);
+    call(VERSION.name(), "5.6.3", firstAnalysis.getUuid());
+    call(VERSION.name(), "6.3", secondAnalysis.getUuid());
 
     List<EventDto> events = dbClient.eventDao().selectByComponentUuid(dbSession, project.uuid());
     assertThat(events).hasSize(2);
@@ -241,13 +209,12 @@ public class CreateEventActionTest {
   public void fail_if_not_blank_name() {
     ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
     SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
-    CreateEventRequest.Builder request = CreateEventRequest.builder().setAnalysis(analysis.getUuid()).setName("    ");
     logInAsProjectAdministrator(project);
 
     expectedException.expect(IllegalArgumentException.class);
     expectedException.expectMessage("A non empty name is required");
 
-    call(request);
+    call(OTHER.name(), "    ", analysis.getUuid());
   }
 
   @Test
@@ -257,46 +224,33 @@ public class CreateEventActionTest {
     expectedException.expect(NotFoundException.class);
     expectedException.expectMessage("Analysis 'A42' is not found");
 
-    CreateEventRequest.Builder request = CreateEventRequest.builder()
-      .setAnalysis("A42")
-      .setCategory(OTHER)
-      .setName("Project Import");
-
-    call(request);
+    call(OTHER.name(), "Project Import", "A42");
   }
 
   @Test
   public void fail_if_2_version_events_on_the_same_analysis() {
     ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
     SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
-    CreateEventRequest.Builder request = CreateEventRequest.builder()
-      .setAnalysis(analysis.getUuid())
-      .setCategory(VERSION)
-      .setName("5.6.3");
     logInAsProjectAdministrator(project);
-    call(request);
+    call(VERSION.name(), "5.6.3", analysis.getUuid());
 
     expectedException.expect(IllegalArgumentException.class);
     expectedException.expectMessage("A version event already exists on analysis '" + analysis.getUuid() + "'");
 
-    call(request.setName("6.3"));
+    call(VERSION.name(), "6.3", analysis.getUuid());
   }
 
   @Test
   public void fail_if_2_other_events_on_same_analysis_with_same_name() {
     ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
     SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
-    CreateEventRequest.Builder request = CreateEventRequest.builder()
-      .setAnalysis(analysis.getUuid())
-      .setCategory(OTHER)
-      .setName("Project Import");
     logInAsProjectAdministrator(project);
-    call(request);
+    call(OTHER.name(), "Project Import", analysis.getUuid());
 
     expectedException.expect(IllegalArgumentException.class);
     expectedException.expectMessage("An 'Other' event with the same name already exists on analysis '" + analysis.getUuid() + "'");
 
-    call(request.setName("Project Import"));
+    call(OTHER.name(), "Project Import", analysis.getUuid());
   }
 
   @Test
@@ -317,32 +271,24 @@ public class CreateEventActionTest {
   public void fail_if_create_on_view() {
     ComponentDto view = newView(db.organizations().insert());
     SnapshotDto analysis = db.components().insertViewAndSnapshot(view);
-    CreateEventRequest.Builder request = CreateEventRequest.builder()
-      .setAnalysis(analysis.getUuid())
-      .setCategory(OTHER)
-      .setName("View Event");
     logInAsProjectAdministrator(view);
 
     expectedException.expect(IllegalArgumentException.class);
     expectedException.expectMessage("An event must be created on a project or an application");
 
-    call(request);
+    call(OTHER.name(), "View Event", analysis.getUuid());
   }
 
   @Test
   public void fail_if_create_version_event_on_application() {
     ComponentDto application = newApplication(db.organizations().insert());
     SnapshotDto analysis = db.components().insertViewAndSnapshot(application);
-    CreateEventRequest.Builder request = CreateEventRequest.builder()
-      .setAnalysis(analysis.getUuid())
-      .setCategory(VERSION)
-      .setName("5.6.3");
     logInAsProjectAdministrator(application);
 
     expectedException.expect(IllegalArgumentException.class);
     expectedException.expectMessage("A version event must be created on a project");
 
-    call(request);
+    call(VERSION.name(), "5.6.3", analysis.getUuid());
   }
 
   @Test
@@ -350,30 +296,22 @@ public class CreateEventActionTest {
     userSession.logIn();
     SnapshotDto analysis = dbClient.snapshotDao().insert(dbSession, newSnapshot().setUuid("A1"));
     db.commit();
-    CreateEventRequest.Builder request = CreateEventRequest.builder()
-      .setAnalysis(analysis.getUuid())
-      .setCategory(VERSION)
-      .setName("5.6.3");
 
     expectedException.expect(IllegalStateException.class);
     expectedException.expectMessage("Project of analysis 'A1' is not found");
 
-    call(request);
+    call(VERSION.name(), "5.6.3", analysis.getUuid());
   }
 
   @Test
   public void throw_ForbiddenException_if_not_project_administrator() {
     SnapshotDto analysis = db.components().insertProjectAndSnapshot(newPrivateProjectDto(db.organizations().insert(), "P1"));
-    CreateEventRequest.Builder request = CreateEventRequest.builder()
-      .setAnalysis(analysis.getUuid())
-      .setCategory(VERSION)
-      .setName("5.6.3");
     userSession.logIn();
 
     expectedException.expect(ForbiddenException.class);
     expectedException.expectMessage("Insufficient privileges");
 
-    call(request);
+    call(VERSION.name(), "5.6.3", analysis.getUuid());
   }
 
   @Test
@@ -389,14 +327,13 @@ public class CreateEventActionTest {
     userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
   }
 
-  private CreateEventResponse call(CreateEventRequest.Builder requestBuilder) {
-    CreateEventRequest request = requestBuilder.build();
+  private CreateEventResponse call(String categoryName, String name, String analysis) {
     TestRequest httpRequest = ws.newRequest()
       .setMethod(POST.name());
 
-    httpRequest.setParam(PARAM_CATEGORY, request.getCategory().name())
-      .setParam(PARAM_NAME, request.getName())
-      .setParam(PARAM_ANALYSIS, request.getAnalysis());
+    httpRequest.setParam(PARAM_CATEGORY, categoryName)
+      .setParam(PARAM_NAME, name)
+      .setParam(PARAM_ANALYSIS, analysis);
 
     return httpRequest.executeProtobuf(CreateEventResponse.class);
   }
index 4d5954ce0fe1e12cbe9b29d171f2e9d6bc4855ae..703d093398ccea7b496db524b153154ad6640f93 100644 (file)
@@ -48,7 +48,6 @@ import org.sonarqube.ws.ProjectAnalyses.Analysis;
 import org.sonarqube.ws.ProjectAnalyses.Event;
 import org.sonarqube.ws.ProjectAnalyses.SearchResponse;
 import org.sonarqube.ws.client.projectanalysis.EventCategory;
-import org.sonarqube.ws.client.projectanalysis.SearchRequest;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.tuple;
index 5de4d8d7e563c505c8a662390d677466b729ab53..25d50b30a30c276652cc71f0bd8e907e5e027334 100644 (file)
@@ -47,12 +47,12 @@ import org.sonar.server.user.index.UserDoc;
 import org.sonar.server.user.index.UserIndex;
 import org.sonar.server.user.index.UserIndexDefinition;
 import org.sonar.server.user.index.UserIndexer;
+import org.sonar.server.user.ws.CreateAction.CreateRequest;
 import org.sonar.server.usergroups.DefaultGroupFinder;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.WsActionTester;
 import org.sonarqube.ws.Users.CreateWsResponse;
 import org.sonarqube.ws.Users.CreateWsResponse.User;
-import org.sonarqube.ws.client.user.CreateRequest;
 
 import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
index 61b5e7741105d3767661c4d53820a7f48de550db..5c8cc2bec0eec7d00db678eb05e2447af3f750ad 100644 (file)
@@ -24,7 +24,7 @@ import java.util.List;
 import static com.google.common.base.Preconditions.checkArgument;
 
 public class SearchRequest {
-  public static final int MAX_NB_PROJECTS = 100;
+  private static final int MAX_NB_PROJECTS = 100;
 
   private final List<String> metricKeys;
   private final List<String> projectKeys;
index a353e7dfb2f7d96caa4b20b28cd9adddbfb3cee9..9d3f046dee63d6c4d3185e20487a0b7ace163d16 100644 (file)
@@ -126,10 +126,10 @@ public class SettingsService extends BaseService {
       new PostRequest(path("set"))
         .setParam("branch", request.getBranch())
         .setParam("component", request.getComponent())
-        .setParam("fieldValues", request.getFieldValues() == null ? null : request.getFieldValues().stream().collect(Collectors.joining(",")))
+        .setParam("fieldValues", request.getFieldValues() == null ? null : request.getFieldValues())
         .setParam("key", request.getKey())
         .setParam("value", request.getValue())
-        .setParam("values", request.getValues() == null ? null : request.getValues().stream().collect(Collectors.joining(",")))
+        .setParam("values", request.getValues() == null ? null : request.getValues())
         .setMediaType(MediaTypes.JSON)
       ).content();
   }
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/ChangePasswordRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/ChangePasswordRequest.java
deleted file mode 100644 (file)
index fe370e4..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.users;
-
-import java.util.List;
-import javax.annotation.Generated;
-
-/**
- * This is part of the internal API.
- * This is a POST request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/change_password">Further information about this action online (including a response example)</a>
- * @since 5.2
- */
-@Generated("sonar-ws-generator")
-public class ChangePasswordRequest {
-
-  private String login;
-  private String password;
-  private String previousPassword;
-
-  /**
-   * This is a mandatory parameter.
-   * Example value: "myuser"
-   */
-  public ChangePasswordRequest setLogin(String login) {
-    this.login = login;
-    return this;
-  }
-
-  public String getLogin() {
-    return login;
-  }
-
-  /**
-   * This is a mandatory parameter.
-   * Example value: "mypassword"
-   */
-  public ChangePasswordRequest setPassword(String password) {
-    this.password = password;
-    return this;
-  }
-
-  public String getPassword() {
-    return password;
-  }
-
-  /**
-   * Example value: "oldpassword"
-   */
-  public ChangePasswordRequest setPreviousPassword(String previousPassword) {
-    this.previousPassword = previousPassword;
-    return this;
-  }
-
-  public String getPreviousPassword() {
-    return previousPassword;
-  }
-}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/CreateRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/CreateRequest.java
deleted file mode 100644 (file)
index 7852c68..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.users;
-
-import java.util.List;
-import javax.annotation.Generated;
-
-/**
- * This is part of the internal API.
- * This is a POST request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/create">Further information about this action online (including a response example)</a>
- * @since 3.7
- */
-@Generated("sonar-ws-generator")
-public class CreateRequest {
-
-  private String email;
-  private String local;
-  private String login;
-  private String name;
-  private String password;
-  private String scmAccount;
-  private String scmAccounts;
-
-  /**
-   * Example value: "myname@email.com"
-   */
-  public CreateRequest setEmail(String email) {
-    this.email = email;
-    return this;
-  }
-
-  public String getEmail() {
-    return email;
-  }
-
-  /**
-   * Possible values:
-   * <ul>
-   *   <li>"true"</li>
-   *   <li>"false"</li>
-   *   <li>"yes"</li>
-   *   <li>"no"</li>
-   * </ul>
-   */
-  public CreateRequest setLocal(String local) {
-    this.local = local;
-    return this;
-  }
-
-  public String getLocal() {
-    return local;
-  }
-
-  /**
-   * This is a mandatory parameter.
-   * Example value: "myuser"
-   */
-  public CreateRequest setLogin(String login) {
-    this.login = login;
-    return this;
-  }
-
-  public String getLogin() {
-    return login;
-  }
-
-  /**
-   * This is a mandatory parameter.
-   * Example value: "My Name"
-   */
-  public CreateRequest setName(String name) {
-    this.name = name;
-    return this;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  /**
-   * Example value: "mypassword"
-   */
-  public CreateRequest setPassword(String password) {
-    this.password = password;
-    return this;
-  }
-
-  public String getPassword() {
-    return password;
-  }
-
-  /**
-   * Example value: "scmAccount=firstValue&scmAccount=secondValue&scmAccount=thirdValue"
-   */
-  public CreateRequest setScmAccount(String scmAccount) {
-    this.scmAccount = scmAccount;
-    return this;
-  }
-
-  public String getScmAccount() {
-    return scmAccount;
-  }
-
-  /**
-   * Example value: "myscmaccount1,myscmaccount2"
-   * @deprecated since 6.1
-   */
-  @Deprecated
-  public CreateRequest setScmAccounts(String scmAccounts) {
-    this.scmAccounts = scmAccounts;
-    return this;
-  }
-
-  public String getScmAccounts() {
-    return scmAccounts;
-  }
-}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/DeactivateRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/DeactivateRequest.java
deleted file mode 100644 (file)
index cf8906d..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.users;
-
-import java.util.List;
-import javax.annotation.Generated;
-
-/**
- * This is part of the internal API.
- * This is a POST request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/deactivate">Further information about this action online (including a response example)</a>
- * @since 3.7
- */
-@Generated("sonar-ws-generator")
-public class DeactivateRequest {
-
-  private String login;
-
-  /**
-   * This is a mandatory parameter.
-   * Example value: "myuser"
-   */
-  public DeactivateRequest setLogin(String login) {
-    this.login = login;
-    return this;
-  }
-
-  public String getLogin() {
-    return login;
-  }
-}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/GroupsRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/GroupsRequest.java
deleted file mode 100644 (file)
index 8db1e4e..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.users;
-
-import java.util.List;
-import javax.annotation.Generated;
-
-/**
- * This is part of the internal API.
- * This is a POST request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/groups">Further information about this action online (including a response example)</a>
- * @since 5.2
- */
-@Generated("sonar-ws-generator")
-public class GroupsRequest {
-
-  private String login;
-  private String organization;
-  private String p;
-  private String ps;
-  private String q;
-  private String selected;
-
-  /**
-   * This is a mandatory parameter.
-   * Example value: "admin"
-   */
-  public GroupsRequest setLogin(String login) {
-    this.login = login;
-    return this;
-  }
-
-  public String getLogin() {
-    return login;
-  }
-
-  /**
-   * This is part of the internal API.
-   * Example value: "my-org"
-   */
-  public GroupsRequest setOrganization(String organization) {
-    this.organization = organization;
-    return this;
-  }
-
-  public String getOrganization() {
-    return organization;
-  }
-
-  /**
-   * Example value: "42"
-   */
-  public GroupsRequest setP(String p) {
-    this.p = p;
-    return this;
-  }
-
-  public String getP() {
-    return p;
-  }
-
-  /**
-   * Example value: "20"
-   */
-  public GroupsRequest setPs(String ps) {
-    this.ps = ps;
-    return this;
-  }
-
-  public String getPs() {
-    return ps;
-  }
-
-  /**
-   * Example value: "users"
-   */
-  public GroupsRequest setQ(String q) {
-    this.q = q;
-    return this;
-  }
-
-  public String getQ() {
-    return q;
-  }
-
-  /**
-   * Possible values:
-   * <ul>
-   *   <li>"all"</li>
-   *   <li>"deselected"</li>
-   *   <li>"selected"</li>
-   * </ul>
-   */
-  public GroupsRequest setSelected(String selected) {
-    this.selected = selected;
-    return this;
-  }
-
-  public String getSelected() {
-    return selected;
-  }
-}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/SearchRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/SearchRequest.java
deleted file mode 100644 (file)
index f7b7967..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.users;
-
-import java.util.List;
-import javax.annotation.Generated;
-
-/**
- * This is part of the internal API.
- * This is a POST request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/search">Further information about this action online (including a response example)</a>
- * @since 3.6
- */
-@Generated("sonar-ws-generator")
-public class SearchRequest {
-
-  private List<String> f;
-  private String p;
-  private String ps;
-  private String q;
-
-  /**
-   * Possible values:
-   * <ul>
-   *   <li>"name"</li>
-   *   <li>"email"</li>
-   *   <li>"avatart"</li>
-   *   <li>"scmAccounts"</li>
-   *   <li>"groups"</li>
-   *   <li>"active"</li>
-   *   <li>"local"</li>
-   *   <li>"externalIdentity"</li>
-   *   <li>"externalProvider"</li>
-   * </ul>
-   * @deprecated since 5.4
-   */
-  @Deprecated
-  public SearchRequest setF(List<String> f) {
-    this.f = f;
-    return this;
-  }
-
-  public List<String> getF() {
-    return f;
-  }
-
-  /**
-   * Example value: "42"
-   */
-  public SearchRequest setP(String p) {
-    this.p = p;
-    return this;
-  }
-
-  public String getP() {
-    return p;
-  }
-
-  /**
-   * Example value: "20"
-   */
-  public SearchRequest setPs(String ps) {
-    this.ps = ps;
-    return this;
-  }
-
-  public String getPs() {
-    return ps;
-  }
-
-  /**
-   */
-  public SearchRequest setQ(String q) {
-    this.q = q;
-    return this;
-  }
-
-  public String getQ() {
-    return q;
-  }
-}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UpdateRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UpdateRequest.java
deleted file mode 100644 (file)
index 672f3c8..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.users;
-
-import java.util.List;
-import javax.annotation.Generated;
-
-/**
- * This is part of the internal API.
- * This is a POST request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/update">Further information about this action online (including a response example)</a>
- * @since 3.7
- */
-@Generated("sonar-ws-generator")
-public class UpdateRequest {
-
-  private String email;
-  private String login;
-  private String name;
-  private String scmAccount;
-  private String scmAccounts;
-
-  /**
-   * Example value: "myname@email.com"
-   */
-  public UpdateRequest setEmail(String email) {
-    this.email = email;
-    return this;
-  }
-
-  public String getEmail() {
-    return email;
-  }
-
-  /**
-   * This is a mandatory parameter.
-   * Example value: "myuser"
-   */
-  public UpdateRequest setLogin(String login) {
-    this.login = login;
-    return this;
-  }
-
-  public String getLogin() {
-    return login;
-  }
-
-  /**
-   * Example value: "My Name"
-   */
-  public UpdateRequest setName(String name) {
-    this.name = name;
-    return this;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  /**
-   * Example value: "scmAccount=firstValue&scmAccount=secondValue&scmAccount=thirdValue"
-   */
-  public UpdateRequest setScmAccount(String scmAccount) {
-    this.scmAccount = scmAccount;
-    return this;
-  }
-
-  public String getScmAccount() {
-    return scmAccount;
-  }
-
-  /**
-   * Example value: "myscmaccount1,myscmaccount2"
-   * @deprecated since 6.1
-   */
-  @Deprecated
-  public UpdateRequest setScmAccounts(String scmAccounts) {
-    this.scmAccounts = scmAccounts;
-    return this;
-  }
-
-  public String getScmAccounts() {
-    return scmAccounts;
-  }
-}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UsersService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UsersService.java
deleted file mode 100644 (file)
index f456762..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.users;
-
-import java.util.stream.Collectors;
-import javax.annotation.Generated;
-import org.sonarqube.ws.MediaTypes;
-import org.sonarqube.ws.client.BaseService;
-import org.sonarqube.ws.client.GetRequest;
-import org.sonarqube.ws.client.PostRequest;
-import org.sonarqube.ws.client.WsConnector;
-import org.sonarqube.ws.Users.CreateWsResponse;
-import org.sonarqube.ws.Users.CurrentWsResponse;
-import org.sonarqube.ws.Users.GroupsWsResponse;
-import org.sonarqube.ws.Users.IdentityProvidersWsResponse;
-import org.sonarqube.ws.Users.SearchWsResponse;
-
-/**
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users">Further information about this web service online</a>
- */
-@Generated("sonar-ws-generator")
-public class UsersService extends BaseService {
-
-  public UsersService(WsConnector wsConnector) {
-    super(wsConnector, "api/users");
-  }
-
-  /**
-   *
-   * This is part of the internal API.
-   * This is a POST request.
-   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/change_password">Further information about this action online (including a response example)</a>
-   * @since 5.2
-   */
-  public void changePassword(ChangePasswordRequest request) {
-    call(
-      new PostRequest(path("change_password"))
-        .setParam("login", request.getLogin())
-        .setParam("password", request.getPassword())
-        .setParam("previousPassword", request.getPreviousPassword())
-        .setMediaType(MediaTypes.JSON)
-      ).content();
-  }
-
-  /**
-   *
-   * This is part of the internal API.
-   * This is a POST request.
-   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/create">Further information about this action online (including a response example)</a>
-   * @since 3.7
-   */
-  public void create(CreateRequest request) {
-    call(
-      new PostRequest(path("create"))
-        .setParam("email", request.getEmail())
-        .setParam("local", request.getLocal())
-        .setParam("login", request.getLogin())
-        .setParam("name", request.getName())
-        .setParam("password", request.getPassword())
-        .setParam("scmAccount", request.getScmAccount())
-        .setParam("scmAccounts", request.getScmAccounts()),
-      CreateWsResponse.parser());
-  }
-
-  /**
-   *
-   * This is part of the internal API.
-   * This is a GET request.
-   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/current">Further information about this action online (including a response example)</a>
-   * @since 5.2
-   */
-  public CurrentWsResponse current() {
-    return call(
-      new GetRequest(path("current")),
-      CurrentWsResponse.parser());
-  }
-
-  /**
-   *
-   * This is part of the internal API.
-   * This is a POST request.
-   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/deactivate">Further information about this action online (including a response example)</a>
-   * @since 3.7
-   */
-  public String deactivate(DeactivateRequest request) {
-    return call(
-      new PostRequest(path("deactivate"))
-        .setParam("login", request.getLogin())
-        .setMediaType(MediaTypes.JSON)
-      ).content();
-  }
-
-  /**
-   *
-   * This is part of the internal API.
-   * This is a GET request.
-   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/groups">Further information about this action online (including a response example)</a>
-   * @since 5.2
-   */
-  public GroupsWsResponse groups(GroupsRequest request) {
-    return call(
-      new GetRequest(path("groups"))
-        .setParam("login", request.getLogin())
-        .setParam("organization", request.getOrganization())
-        .setParam("p", request.getP())
-        .setParam("ps", request.getPs())
-        .setParam("q", request.getQ())
-        .setParam("selected", request.getSelected()),
-      GroupsWsResponse.parser());
-  }
-
-  /**
-   *
-   * This is part of the internal API.
-   * This is a GET request.
-   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/identity_providers">Further information about this action online (including a response example)</a>
-   * @since 5.5
-   */
-  public IdentityProvidersWsResponse identityProviders() {
-    return call(
-      new GetRequest(path("identity_providers")),
-      IdentityProvidersWsResponse.parser());
-  }
-
-  /**
-   *
-   * This is part of the internal API.
-   * This is a GET request.
-   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/search">Further information about this action online (including a response example)</a>
-   * @since 3.6
-   */
-  public SearchWsResponse search(SearchRequest request) {
-    return call(
-      new GetRequest(path("search"))
-        .setParam("f", request.getF() == null ? null : request.getF().stream().collect(Collectors.joining(",")))
-        .setParam("p", request.getP())
-        .setParam("ps", request.getPs())
-        .setParam("q", request.getQ()),
-      SearchWsResponse.parser());
-  }
-
-  /**
-   *
-   * This is part of the internal API.
-   * This is a POST request.
-   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/skip_onboarding_tutorial">Further information about this action online (including a response example)</a>
-   * @since 6.5
-   */
-  public void skipOnboardingTutorial() {
-    call(
-      new PostRequest(path("skip_onboarding_tutorial"))
-        .setMediaType(MediaTypes.JSON)
-      ).content();
-  }
-
-  /**
-   *
-   * This is part of the internal API.
-   * This is a POST request.
-   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/users/update">Further information about this action online (including a response example)</a>
-   * @since 3.7
-   */
-  public String update(UpdateRequest request) {
-    return call(
-      new PostRequest(path("update"))
-        .setParam("email", request.getEmail())
-        .setParam("login", request.getLogin())
-        .setParam("name", request.getName())
-        .setParam("scmAccount", request.getScmAccount())
-        .setParam("scmAccounts", request.getScmAccounts())
-        .setMediaType(MediaTypes.JSON)
-      ).content();
-  }
-}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/package-info.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/package-info.java
deleted file mode 100644 (file)
index 90f68b1..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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
-@Generated("sonar-ws-generator")
-package org.sonarqube.ws.client.users;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.Generated;
-