@@ -20,6 +20,8 @@ | |||
package org.sonar.server.permission; | |||
import org.sonar.api.server.ws.WebService.SelectionMode; | |||
import org.sonar.core.permission.PermissionQuery; | |||
import org.sonar.core.user.GroupMembershipQuery; | |||
import org.sonar.server.util.RubyUtils; | |||
@@ -28,9 +30,6 @@ import java.util.Map; | |||
public class PermissionQueryParser { | |||
private static final String SELECTED_MEMBERSHIP = "selected"; | |||
private static final String DESELECTED_MEMBERSHIP = "deselected"; | |||
private PermissionQueryParser(){ | |||
// Utility class | |||
} | |||
@@ -48,10 +47,10 @@ public class PermissionQueryParser { | |||
} | |||
private static String membership(Map<String, Object> params) { | |||
String selected = (String) params.get("selected"); | |||
if (SELECTED_MEMBERSHIP.equals(selected)) { | |||
SelectionMode selectionMode = SelectionMode.fromParam((String) params.get("selected")); | |||
if (SelectionMode.SELECTED == selectionMode) { | |||
return GroupMembershipQuery.IN; | |||
} else if (DESELECTED_MEMBERSHIP.equals(selected)) { | |||
} else if (SelectionMode.DESELECTED == selectionMode) { | |||
return GroupMembershipQuery.OUT; | |||
} else { | |||
return GroupMembershipQuery.ANY; |
@@ -31,7 +31,6 @@ public class QGatesWs implements WebService { | |||
static final String PARAM_PAGE_SIZE = "pageSize"; | |||
static final String PARAM_PAGE = "page"; | |||
static final String PARAM_QUERY = "query"; | |||
static final String PARAM_SELECTED = "selected"; | |||
static final String PARAM_NAME = "name"; | |||
static final String PARAM_ERROR = "error"; | |||
static final String PARAM_WARNING = "warning"; |
@@ -20,6 +20,8 @@ | |||
package org.sonar.server.qualitygate.ws; | |||
import org.sonar.api.server.ws.WebService.Param; | |||
import com.google.common.io.Resources; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
@@ -54,11 +56,7 @@ public class SearchAction implements QGateWsAction { | |||
.setDescription("To search for projects containing this string. If this parameter is set, \"selected\" is set to \"all\".") | |||
.setExampleValue("abc"); | |||
action.createParam(QGatesWs.PARAM_SELECTED) | |||
.setDescription("If \"selected\", search for projects associated to the quality gate") | |||
.setDefaultValue(ProjectQgateAssociationQuery.IN) | |||
.setPossibleValues(ProjectQgateAssociationQuery.AVAILABLE_MEMBERSHIP) | |||
.setExampleValue(ProjectQgateAssociationQuery.OUT); | |||
action.addSelectionModeParam(); | |||
action.createParam(QGatesWs.PARAM_PAGE) | |||
.setDescription("Page number") | |||
@@ -74,7 +72,7 @@ public class SearchAction implements QGateWsAction { | |||
public void handle(Request request, Response response) { | |||
QgateProjectFinder.Association associations = projectFinder.find(ProjectQgateAssociationQuery.builder() | |||
.gateId(request.mandatoryParam(QGatesWs.PARAM_GATE_ID)) | |||
.membership(request.param(QGatesWs.PARAM_QUERY) == null ? request.param(QGatesWs.PARAM_SELECTED) : ProjectQgateAssociationQuery.ANY) | |||
.membership(request.param(QGatesWs.PARAM_QUERY) == null ? request.param(Param.SELECTED) : ProjectQgateAssociationQuery.ANY) | |||
.projectSearch(request.param(QGatesWs.PARAM_QUERY)) | |||
.pageIndex(request.paramAsInt(QGatesWs.PARAM_PAGE)) | |||
.pageSize(request.paramAsInt(QGatesWs.PARAM_PAGE_SIZE)) | |||
@@ -83,7 +81,7 @@ public class SearchAction implements QGateWsAction { | |||
writer.beginObject().prop("more", associations.hasMoreResults()); | |||
writer.name("results").beginArray(); | |||
for (ProjectQgateAssociation project : associations.projects()) { | |||
writer.beginObject().prop("id", project.id()).prop("name", project.name()).prop(QGatesWs.PARAM_SELECTED, project.isMember()).endObject(); | |||
writer.beginObject().prop("id", project.id()).prop("name", project.name()).prop(Param.SELECTED, project.isMember()).endObject(); | |||
} | |||
writer.endArray().endObject().close(); | |||
} |
@@ -19,6 +19,9 @@ | |||
*/ | |||
package org.sonar.server.qualityprofile.ws; | |||
import org.sonar.api.server.ws.WebService.Param; | |||
import org.sonar.api.server.ws.WebService.SelectionMode; | |||
import com.google.common.base.Predicate; | |||
import com.google.common.collect.Collections2; | |||
import com.google.common.collect.Iterables; | |||
@@ -46,15 +49,10 @@ import java.util.List; | |||
public class ProjectsAction implements QProfileWsAction { | |||
private static final String PARAM_KEY = "key"; | |||
private static final String PARAM_SELECTED = "selected"; | |||
private static final String PARAM_QUERY = "query"; | |||
private static final String PARAM_PAGE_SIZE = "pageSize"; | |||
private static final String PARAM_PAGE = "page"; | |||
private static final String SELECTION_ALL = "all"; | |||
private static final String SELECTION_SELECTED = "selected"; | |||
private static final String SELECTION_DESELECTED = "deselected"; | |||
private final DbClient dbClient; | |||
private final UserSession userSession; | |||
@@ -74,10 +72,7 @@ public class ProjectsAction implements QProfileWsAction { | |||
.setDescription("A quality profile key.") | |||
.setRequired(true) | |||
.setExampleValue("sonar-way-java-12345"); | |||
projects.createParam(PARAM_SELECTED) | |||
.setDescription("If specified, return only selected or deselected projects.") | |||
.setPossibleValues(SELECTION_SELECTED, SELECTION_DESELECTED, SELECTION_ALL) | |||
.setDefaultValue(SELECTION_ALL); | |||
projects.addSelectionModeParam(); | |||
projects.createParam(PARAM_QUERY) | |||
.setDescription("If specified, return only projects whose name match the query."); | |||
projects.createParam(PARAM_PAGE_SIZE) | |||
@@ -94,7 +89,7 @@ public class ProjectsAction implements QProfileWsAction { | |||
try { | |||
checkProfileExists(profileKey, session); | |||
String selected = request.param(PARAM_SELECTED); | |||
String selected = request.param(Param.SELECTED); | |||
String query = request.param(PARAM_QUERY); | |||
int pageSize = request.mandatoryParamAsInt(PARAM_PAGE_SIZE); | |||
int page = request.mandatoryParamAsInt(PARAM_PAGE); | |||
@@ -151,9 +146,10 @@ public class ProjectsAction implements QProfileWsAction { | |||
private List<ProjectQprofileAssociationDto> loadProjects(String profileKey, DbSession session, String selected, String query) { | |||
List<ProjectQprofileAssociationDto> projects = Lists.newArrayList(); | |||
if (SELECTION_SELECTED.equals(selected)) { | |||
SelectionMode selectionMode = SelectionMode.fromParam(selected); | |||
if (SelectionMode.SELECTED == selectionMode) { | |||
projects.addAll(dbClient.qualityProfileDao().selectSelectedProjects(profileKey, query, session)); | |||
} else if (SELECTION_DESELECTED.equals(selected)) { | |||
} else if (SelectionMode.DESELECTED == selectionMode) { | |||
projects.addAll(dbClient.qualityProfileDao().selectDeselectedProjects(profileKey, query, session)); | |||
} else { | |||
projects.addAll(dbClient.qualityProfileDao().selectProjectAssociations(profileKey, query, session)); |
@@ -20,12 +20,12 @@ | |||
package org.sonar.server.user.ws; | |||
import java.util.List; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService.NewAction; | |||
import org.sonar.api.server.ws.WebService.NewController; | |||
import org.sonar.api.server.ws.WebService.Param; | |||
import org.sonar.api.server.ws.WebService.SelectionMode; | |||
import org.sonar.api.utils.Paging; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
@@ -39,15 +39,10 @@ import org.sonar.server.user.UserSession; | |||
public class GroupsAction implements UsersWsAction { | |||
private static final String PARAM_LOGIN = "login"; | |||
private static final String PARAM_SELECTED = "selected"; | |||
private static final String SELECTION_ALL = "all"; | |||
private static final String SELECTION_SELECTED = PARAM_SELECTED; | |||
private static final String SELECTION_DESELECTED = "deselected"; | |||
private static final String FIELD_SELECTED = PARAM_SELECTED; | |||
private static final String FIELD_DESCRIPTION = "description"; | |||
private static final String FIELD_NAME = "name"; | |||
private static final String FIELD_DESCRIPTION = "description"; | |||
private static final String FIELD_SELECTED = "selected"; | |||
private final DbClient dbClient; | |||
private final UserSession userSession; | |||
@@ -70,14 +65,9 @@ public class GroupsAction implements UsersWsAction { | |||
.setExampleValue("admin") | |||
.setRequired(true); | |||
action.createParam(PARAM_SELECTED) | |||
.setDescription("If specified, only show groups the user is member of (selected) or not (deselected).") | |||
.setPossibleValues(SELECTION_SELECTED, SELECTION_DESELECTED, SELECTION_ALL) | |||
.setDefaultValue(SELECTION_ALL); | |||
action.addSelectionModeParam(); | |||
action.createParam(Param.TEXT_QUERY) | |||
.setDescription("If specified, only show groups whose name contains the query.") | |||
.setExampleValue("user"); | |||
action.addSearchQuery("users", "group names"); | |||
action.addPagingParams(25); | |||
} | |||
@@ -90,7 +80,7 @@ public class GroupsAction implements UsersWsAction { | |||
int pageSize = request.mandatoryParamAsInt(Param.PAGE_SIZE); | |||
int page = request.mandatoryParamAsInt(Param.PAGE); | |||
String queryString = request.param(Param.TEXT_QUERY); | |||
String selected = request.param(PARAM_SELECTED); | |||
String selected = request.mandatoryParam(Param.SELECTED); | |||
GroupMembershipQuery query = GroupMembershipQuery.builder() | |||
.login(login) | |||
@@ -116,7 +106,7 @@ public class GroupsAction implements UsersWsAction { | |||
} | |||
} | |||
private void writeGroups(JsonWriter json, List<GroupMembershipDto> groups) { | |||
private static void writeGroups(JsonWriter json, List<GroupMembershipDto> groups) { | |||
json.name("groups").beginArray(); | |||
for (GroupMembershipDto group : groups) { | |||
json.beginObject() | |||
@@ -128,17 +118,18 @@ public class GroupsAction implements UsersWsAction { | |||
json.endArray(); | |||
} | |||
private void writePaging(JsonWriter json, Paging paging) { | |||
private static void writePaging(JsonWriter json, Paging paging) { | |||
json.prop("p", paging.pageIndex()) | |||
.prop("ps", paging.pageSize()) | |||
.prop("total", paging.total()); | |||
} | |||
private String getMembership(@Nullable String selected) { | |||
private String getMembership(String selected) { | |||
SelectionMode selectionMode = SelectionMode.fromParam(selected); | |||
String membership = GroupMembershipQuery.ANY; | |||
if (SELECTION_SELECTED.equals(selected)) { | |||
if (SelectionMode.SELECTED == selectionMode) { | |||
membership = GroupMembershipQuery.IN; | |||
} else if (SELECTION_DESELECTED.equals(selected)) { | |||
} else if (SelectionMode.DESELECTED == selectionMode) { | |||
membership = GroupMembershipQuery.OUT; | |||
} | |||
return membership; |
@@ -20,12 +20,12 @@ | |||
package org.sonar.server.usergroups.ws; | |||
import java.util.List; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService.NewAction; | |||
import org.sonar.api.server.ws.WebService.NewController; | |||
import org.sonar.api.server.ws.WebService.Param; | |||
import org.sonar.api.server.ws.WebService.SelectionMode; | |||
import org.sonar.api.utils.Paging; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
@@ -40,13 +40,8 @@ import org.sonar.server.user.UserSession; | |||
public class UsersAction implements UserGroupsWsAction { | |||
private static final String PARAM_ID = "id"; | |||
private static final String PARAM_SELECTED = "selected"; | |||
private static final String SELECTION_ALL = "all"; | |||
private static final String SELECTION_SELECTED = PARAM_SELECTED; | |||
private static final String SELECTION_DESELECTED = "deselected"; | |||
private static final String FIELD_SELECTED = PARAM_SELECTED; | |||
private static final String FIELD_SELECTED = "selected"; | |||
private static final String FIELD_NAME = "name"; | |||
private static final String FIELD_LOGIN = "login"; | |||
@@ -71,10 +66,7 @@ public class UsersAction implements UserGroupsWsAction { | |||
.setExampleValue("42") | |||
.setRequired(true); | |||
action.createParam(PARAM_SELECTED) | |||
.setDescription("If specified, only show users who belong to a group (selected=selected) or only those who do not (selected=deselected).") | |||
.setPossibleValues(SELECTION_SELECTED, SELECTION_DESELECTED, SELECTION_ALL) | |||
.setDefaultValue(SELECTION_ALL); | |||
action.addSelectionModeParam(); | |||
action.addSearchQuery("freddy", "names", "logins"); | |||
@@ -89,7 +81,7 @@ public class UsersAction implements UserGroupsWsAction { | |||
int pageSize = request.mandatoryParamAsInt(Param.PAGE_SIZE); | |||
int page = request.mandatoryParamAsInt(Param.PAGE); | |||
String queryString = request.param(Param.TEXT_QUERY); | |||
String selected = request.param(PARAM_SELECTED); | |||
String selected = request.mandatoryParam(Param.SELECTED); | |||
UserMembershipQuery query = UserMembershipQuery.builder() | |||
.groupId(groupId) | |||
@@ -115,7 +107,7 @@ public class UsersAction implements UserGroupsWsAction { | |||
} | |||
} | |||
private void writeMembers(JsonWriter json, List<UserMembershipDto> users) { | |||
private static void writeMembers(JsonWriter json, List<UserMembershipDto> users) { | |||
json.name("users").beginArray(); | |||
for (UserMembershipDto user : users) { | |||
json.beginObject() | |||
@@ -127,17 +119,18 @@ public class UsersAction implements UserGroupsWsAction { | |||
json.endArray(); | |||
} | |||
private void writePaging(JsonWriter json, Paging paging) { | |||
private static void writePaging(JsonWriter json, Paging paging) { | |||
json.prop(Param.PAGE, paging.pageIndex()) | |||
.prop(Param.PAGE_SIZE, paging.pageSize()) | |||
.prop("total", paging.total()); | |||
} | |||
private String getMembership(@Nullable String selected) { | |||
private String getMembership(String selected) { | |||
SelectionMode selectionMode = SelectionMode.fromParam(selected); | |||
String membership = GroupMembershipQuery.ANY; | |||
if (SELECTION_SELECTED.equals(selected)) { | |||
if (SelectionMode.SELECTED == selectionMode) { | |||
membership = GroupMembershipQuery.IN; | |||
} else if (SELECTION_DESELECTED.equals(selected)) { | |||
} else if (SelectionMode.DESELECTED == selectionMode) { | |||
membership = GroupMembershipQuery.OUT; | |||
} | |||
return membership; |
@@ -26,6 +26,7 @@ import org.junit.ClassRule; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.sonar.api.server.ws.WebService.Param; | |||
import org.sonar.api.server.ws.WebService.SelectionMode; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.core.persistence.DbSession; | |||
@@ -111,6 +112,7 @@ public class GroupsActionTest { | |||
tester.newGetRequest("api/users", "groups") | |||
.setParam("login", "john") | |||
.setParam(Param.SELECTED, SelectionMode.ALL.value()) | |||
.execute() | |||
.assertJson(getClass(), "all.json"); | |||
} | |||
@@ -125,7 +127,12 @@ public class GroupsActionTest { | |||
tester.newGetRequest("api/users", "groups") | |||
.setParam("login", "john") | |||
.setParam("selected", "selected") | |||
.execute() | |||
.assertJson(getClass(), "selected.json"); | |||
tester.newGetRequest("api/users", "groups") | |||
.setParam("login", "john") | |||
.setParam(Param.SELECTED, SelectionMode.SELECTED.value()) | |||
.execute() | |||
.assertJson(getClass(), "selected.json"); | |||
} | |||
@@ -140,7 +147,7 @@ public class GroupsActionTest { | |||
tester.newGetRequest("api/users", "groups") | |||
.setParam("login", "john") | |||
.setParam("selected", "deselected") | |||
.setParam(Param.SELECTED, SelectionMode.DESELECTED.value()) | |||
.execute() | |||
.assertJson(getClass(), "deselected.json"); | |||
} | |||
@@ -165,6 +172,7 @@ public class GroupsActionTest { | |||
tester.newGetRequest("api/users", "groups") | |||
.setParam("login", "john") | |||
.setParam(Param.PAGE_SIZE, "1") | |||
.setParam(Param.SELECTED, SelectionMode.ALL.value()) | |||
.execute() | |||
.assertJson(getClass(), "all_page1.json"); | |||
@@ -172,6 +180,7 @@ public class GroupsActionTest { | |||
.setParam("login", "john") | |||
.setParam(Param.PAGE_SIZE, "1") | |||
.setParam(Param.PAGE, "2") | |||
.setParam(Param.SELECTED, SelectionMode.ALL.value()) | |||
.execute() | |||
.assertJson(getClass(), "all_page2.json"); | |||
} | |||
@@ -187,12 +196,14 @@ public class GroupsActionTest { | |||
tester.newGetRequest("api/users", "groups") | |||
.setParam("login", "john") | |||
.setParam("q", "users") | |||
.setParam(Param.SELECTED, SelectionMode.ALL.value()) | |||
.execute() | |||
.assertJson(getClass(), "all_users.json"); | |||
tester.newGetRequest("api/users", "groups") | |||
.setParam("login", "john") | |||
.setParam("q", "admin") | |||
.setParam(Param.SELECTED, SelectionMode.ALL.value()) | |||
.execute() | |||
.assertJson(getClass(), "all_admin.json"); | |||
} |
@@ -26,6 +26,8 @@ import org.junit.ClassRule; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.experimental.categories.Category; | |||
import org.sonar.api.server.ws.WebService.Param; | |||
import org.sonar.api.server.ws.WebService.SelectionMode; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.core.persistence.DbSession; | |||
@@ -122,6 +124,7 @@ public class UsersActionTest { | |||
newUsersRequest() | |||
.setParam("id", group.getId().toString()) | |||
.setParam(Param.SELECTED, SelectionMode.ALL.value()) | |||
.execute() | |||
.assertJson(getClass(), "all.json"); | |||
} | |||
@@ -136,7 +139,12 @@ public class UsersActionTest { | |||
newUsersRequest() | |||
.setParam("id", group.getId().toString()) | |||
.setParam("selected", "selected") | |||
.execute() | |||
.assertJson(getClass(), "selected.json"); | |||
newUsersRequest() | |||
.setParam("id", group.getId().toString()) | |||
.setParam(Param.SELECTED, SelectionMode.SELECTED.value()) | |||
.execute() | |||
.assertJson(getClass(), "selected.json"); | |||
} | |||
@@ -151,7 +159,7 @@ public class UsersActionTest { | |||
newUsersRequest() | |||
.setParam("id", group.getId().toString()) | |||
.setParam("selected", "deselected") | |||
.setParam(Param.SELECTED, SelectionMode.DESELECTED.value()) | |||
.execute() | |||
.assertJson(getClass(), "deselected.json"); | |||
} | |||
@@ -167,6 +175,7 @@ public class UsersActionTest { | |||
newUsersRequest() | |||
.setParam("id", group.getId().toString()) | |||
.setParam("ps", "1") | |||
.setParam(Param.SELECTED, SelectionMode.ALL.value()) | |||
.execute() | |||
.assertJson(getClass(), "all_page1.json"); | |||
@@ -174,6 +183,7 @@ public class UsersActionTest { | |||
.setParam("id", group.getId().toString()) | |||
.setParam("ps", "1") | |||
.setParam("p", "2") | |||
.setParam(Param.SELECTED, SelectionMode.ALL.value()) | |||
.execute() | |||
.assertJson(getClass(), "all_page2.json"); | |||
} | |||
@@ -189,6 +199,7 @@ public class UsersActionTest { | |||
newUsersRequest() | |||
.setParam("id", group.getId().toString()) | |||
.setParam("q", "ace") | |||
.setParam(Param.SELECTED, SelectionMode.ALL.value()) | |||
.execute() | |||
.assertJson(getClass(), "all.json"); | |||
@@ -19,7 +19,9 @@ | |||
*/ | |||
package org.sonar.api.server.ws; | |||
import com.google.common.base.Function; | |||
import com.google.common.base.Joiner; | |||
import com.google.common.base.Preconditions; | |||
import com.google.common.collect.ImmutableList; | |||
import com.google.common.collect.ImmutableMap; | |||
import com.google.common.collect.Maps; | |||
@@ -33,6 +35,7 @@ import java.util.List; | |||
import java.util.Map; | |||
import java.util.Set; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nonnull; | |||
import javax.annotation.Nullable; | |||
import javax.annotation.concurrent.Immutable; | |||
import org.apache.commons.io.FilenameUtils; | |||
@@ -385,6 +388,18 @@ public interface WebService extends Definable<WebService.Context> { | |||
.setDefaultValue(defaultAscending); | |||
return this; | |||
} | |||
/** | |||
* Add 'selected=(selected|deselected|all)' for select-list oriented WS. | |||
*/ | |||
public NewAction addSelectionModeParam() { | |||
createParam(Param.SELECTED) | |||
.setDescription("Depending on the value, show only selected items (selected=selected), deselected items (selected=deselected), " + | |||
"or all items with their selection status (selected=all).") | |||
.setDefaultValue(SelectionMode.SELECTED.value()) | |||
.setPossibleValues(SelectionMode.possibleValues()); | |||
return this; | |||
} | |||
} | |||
@Immutable | |||
@@ -592,6 +607,36 @@ public interface WebService extends Definable<WebService.Context> { | |||
} | |||
} | |||
enum SelectionMode { | |||
SELECTED("selected"), DESELECTED("deselected"), ALL("all"); | |||
private final String paramValue; | |||
private static final Map<String, SelectionMode> BY_VALUE = Maps.uniqueIndex(Arrays.asList(values()), new Function<SelectionMode, String>() { | |||
@Override | |||
public String apply(@Nonnull SelectionMode input) { | |||
return input.paramValue; | |||
} | |||
}); | |||
private SelectionMode(String paramValue) { | |||
this.paramValue = paramValue; | |||
} | |||
public String value() { | |||
return paramValue; | |||
} | |||
public static SelectionMode fromParam(String paramValue) { | |||
Preconditions.checkArgument(BY_VALUE.containsKey(paramValue)); | |||
return BY_VALUE.get(paramValue); | |||
} | |||
public static Collection<String> possibleValues() { | |||
return BY_VALUE.keySet(); | |||
} | |||
} | |||
@Immutable | |||
class Param { | |||
public static final String TEXT_QUERY = "q"; | |||
@@ -601,6 +646,7 @@ public interface WebService extends Definable<WebService.Context> { | |||
public static final String SORT = "s"; | |||
public static final String ASCENDING = "asc"; | |||
public static final String FACETS = "facets"; | |||
public static final String SELECTED = "selected"; | |||
private final String key, deprecatedKey, description, exampleValue, defaultValue; | |||
private final boolean required; |