From cf6e592d4967864c8a7f1ed8a0676ab1add70748 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lievremont Date: Tue, 2 Jun 2015 11:03:34 +0200 Subject: [PATCH] Refactor handling of 'selection mode' for WS actions --- .../permission/PermissionQueryParser.java | 11 ++--- .../sonar/server/qualitygate/ws/QGatesWs.java | 1 - .../server/qualitygate/ws/SearchAction.java | 12 ++--- .../qualityprofile/ws/ProjectsAction.java | 20 ++++---- .../sonar/server/user/ws/GroupsAction.java | 33 +++++-------- .../server/usergroups/ws/UsersAction.java | 27 ++++------- .../server/user/ws/GroupsActionTest.java | 15 +++++- .../server/usergroups/ws/UsersActionTest.java | 15 +++++- .../org/sonar/api/server/ws/WebService.java | 46 +++++++++++++++++++ 9 files changed, 112 insertions(+), 68 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionQueryParser.java b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionQueryParser.java index 0384a735ef6..8d16f383bb6 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionQueryParser.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionQueryParser.java @@ -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 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; diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesWs.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesWs.java index bb8bff8abba..514e8d4a655 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesWs.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesWs.java @@ -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"; diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java index 24ccf061c53..69268b929ec 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java @@ -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(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ProjectsAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ProjectsAction.java index f4b3bc9658f..fb6349e77e4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ProjectsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ProjectsAction.java @@ -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 loadProjects(String profileKey, DbSession session, String selected, String query) { List 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)); diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java index 9538cd93104..b713e9a6ed2 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java @@ -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 groups) { + private static void writeGroups(JsonWriter json, List 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; diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UsersAction.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UsersAction.java index 526ddd114b9..6cb3a52d35f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UsersAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UsersAction.java @@ -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 users) { + private static void writeMembers(JsonWriter json, List 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; diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/GroupsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/GroupsActionTest.java index c35d5cb0a06..d57b5baa082 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/GroupsActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/GroupsActionTest.java @@ -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"); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UsersActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UsersActionTest.java index 30c31d346cc..c7288d6d818 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UsersActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UsersActionTest.java @@ -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"); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java index 49c9c0adf2c..418caff6e84 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java @@ -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 { .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 { } } + enum SelectionMode { + SELECTED("selected"), DESELECTED("deselected"), ALL("all"); + + private final String paramValue; + + private static final Map BY_VALUE = Maps.uniqueIndex(Arrays.asList(values()), new Function() { + @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 possibleValues() { + return BY_VALUE.keySet(); + } + } + @Immutable class Param { public static final String TEXT_QUERY = "q"; @@ -601,6 +646,7 @@ public interface WebService extends Definable { 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; -- 2.39.5