src/com/gitblit/GitBlit.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/models/TeamAccessPermission.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/models/UserAccessPermission.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/pages/EditRepositoryPage.html | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/pages/EditRepositoryPage.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/panels/TeamPermissionsPanel.html | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/panels/TeamPermissionsPanel.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/panels/UserPermissionsPanel.html | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/panels/UserPermissionsPanel.java | ●●●●● patch | view | raw | blame | history |
src/com/gitblit/GitBlit.java
@@ -89,7 +89,9 @@ import com.gitblit.models.ServerSettings; import com.gitblit.models.ServerStatus; import com.gitblit.models.SettingModel; import com.gitblit.models.TeamAccessPermission; import com.gitblit.models.TeamModel; import com.gitblit.models.UserAccessPermission; import com.gitblit.models.UserModel; import com.gitblit.utils.ArrayUtils; import com.gitblit.utils.ByteFormat; @@ -630,12 +632,44 @@ } /** * Returns the list of all users who are allowed to bypass the access * restriction placed on the specified repository. * Returns the list of users and their access permissions for the specified repository. * * @param repository * @return a list of User-AccessPermission tuples */ public List<UserAccessPermission> getUserAccessPermissions(RepositoryModel repository) { List<UserAccessPermission> permissions = new ArrayList<UserAccessPermission>(); for (String user : userService.getUsernamesForRepositoryRole(repository.name)) { AccessPermission ap = userService.getUserModel(user).getRepositoryPermission(repository); permissions.add(new UserAccessPermission(user, ap)); } return permissions; } /** * Sets the access permissions to the specified repository for the specified users. * * @param repository * @param permissions * @return true if the user models have been updated */ public boolean setUserAccessPermissions(RepositoryModel repository, List<UserAccessPermission> permissions) { List<UserModel> users = new ArrayList<UserModel>(); for (UserAccessPermission up : permissions) { UserModel user = userService.getUserModel(up.user); user.setRepositoryPermission(repository.name, up.permission); users.add(user); } return userService.updateUserModels(users); } /** * Returns the list of all users who have an explicit access permission * for the specified repository. * * @see IUserService.getUsernamesForRepositoryRole(String) * @param repository * @return list of all usernames that can bypass the access restriction * @return list of all usernames that have an access permission for the repository */ public List<String> getRepositoryUsers(RepositoryModel repository) { return userService.getUsernamesForRepositoryRole(repository.name); @@ -728,6 +762,38 @@ } /** * Returns the list of teams and their access permissions for the specified repository. * * @param repository * @return a list of Team-AccessPermission tuples */ public List<TeamAccessPermission> getTeamAccessPermissions(RepositoryModel repository) { List<TeamAccessPermission> permissions = new ArrayList<TeamAccessPermission>(); for (String team : userService.getTeamnamesForRepositoryRole(repository.name)) { AccessPermission ap = userService.getTeamModel(team).getRepositoryPermission(repository); permissions.add(new TeamAccessPermission(team, ap)); } return permissions; } /** * Sets the access permissions to the specified repository for the specified teams. * * @param repository * @param permissions * @return true if the team models have been updated */ public boolean setTeamAccessPermissions(RepositoryModel repository, List<TeamAccessPermission> permissions) { List<TeamModel> teams = new ArrayList<TeamModel>(); for (TeamAccessPermission tp : permissions) { TeamModel team = userService.getTeamModel(tp.team); team.setRepositoryPermission(repository.name, tp.permission); teams.add(team); } return userService.updateTeamModels(teams); } /** * Returns the list of all teams who are allowed to bypass the access * restriction placed on the specified repository. * @@ -735,6 +801,7 @@ * @param repository * @return list of all teamnames that can bypass the access restriction */ @Deprecated public List<String> getRepositoryTeams(RepositoryModel repository) { return userService.getTeamnamesForRepositoryRole(repository.name); } src/com/gitblit/models/TeamAccessPermission.java
New file @@ -0,0 +1,51 @@ /* * Copyright 2012 gitblit.com. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gitblit.models; import java.io.Serializable; import com.gitblit.Constants.AccessPermission; /** * Represents a Team-AccessPermission tuple. * * @author James Moger */ public class TeamAccessPermission implements Serializable, Comparable<TeamAccessPermission> { private static final long serialVersionUID = 1L; public String team; public AccessPermission permission; public TeamAccessPermission() { } public TeamAccessPermission(String team, AccessPermission permission) { this.team = team; this.permission = permission; } @Override public int compareTo(TeamAccessPermission p) { return team.compareTo(p.team); } @Override public String toString() { return permission.asRole("@" + team); } } src/com/gitblit/models/UserAccessPermission.java
New file @@ -0,0 +1,51 @@ /* * Copyright 2012 gitblit.com. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gitblit.models; import java.io.Serializable; import com.gitblit.Constants.AccessPermission; /** * Represents a User-AccessPermission tuple. * * @author James Moger */ public class UserAccessPermission implements Serializable, Comparable<UserAccessPermission> { private static final long serialVersionUID = 1L; public String user; public AccessPermission permission; public UserAccessPermission() { } public UserAccessPermission(String user, AccessPermission permission) { this.user = user; this.permission = permission; } @Override public int compareTo(UserAccessPermission p) { return user.compareTo(p.user); } @Override public String toString() { return permission.asRole(user); } } src/com/gitblit/wicket/pages/EditRepositoryPage.html
@@ -38,6 +38,7 @@ <tr><th><wicket:message key="gb.verifyCommitter"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="verifyCommitter" tabindex="18" /> <span class="help-inline"><wicket:message key="gb.verifyCommitterDescription"></wicket:message></span></label></td></tr> <tr><th colspan="2"><hr/></th></tr> <tr><th style="vertical-align: top;"><wicket:message key="gb.permittedUsers"></wicket:message></th><td style="padding:2px;"><span wicket:id="users"></span></td></tr> <tr><th colspan="2"><hr/></th></tr> <tr><th style="vertical-align: top;"><wicket:message key="gb.permittedTeams"></wicket:message></th><td style="padding:2px;"><span wicket:id="teams"></span></td></tr> <tr><td colspan="2"><h3><wicket:message key="gb.federation"></wicket:message> <small><wicket:message key="gb.federationRepositoryDescription"></wicket:message></small></h3></td></tr> <tr><th><wicket:message key="gb.federationStrategy"></wicket:message></th><td class="edit"><select class="span4" wicket:id="federationStrategy" tabindex="19" /></td></tr> src/com/gitblit/wicket/pages/EditRepositoryPage.java
@@ -55,6 +55,8 @@ import com.gitblit.GitBlitException; import com.gitblit.Keys; import com.gitblit.models.RepositoryModel; import com.gitblit.models.TeamAccessPermission; import com.gitblit.models.UserAccessPermission; import com.gitblit.models.UserModel; import com.gitblit.utils.ArrayUtils; import com.gitblit.utils.StringUtils; @@ -62,6 +64,8 @@ import com.gitblit.wicket.StringChoiceRenderer; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.panels.BulletListPanel; import com.gitblit.wicket.panels.TeamPermissionsPanel; import com.gitblit.wicket.panels.UserPermissionsPanel; public class EditRepositoryPage extends RootSubPage { @@ -94,6 +98,7 @@ } setupPage(model); setStatelessHint(false); } public EditRepositoryPage(PageParameters params) { @@ -103,6 +108,7 @@ String name = WicketUtils.getRepositoryName(params); RepositoryModel model = GitBlit.self().getRepositoryModel(name); setupPage(model); setStatelessHint(false); } protected void setupPage(final RepositoryModel repositoryModel) { @@ -111,8 +117,8 @@ List<String> indexedBranches = new ArrayList<String>(); List<String> federationSets = new ArrayList<String>(); List<String> repositoryUsers = new ArrayList<String>(); List<String> repositoryTeams = new ArrayList<String>(); final List<UserAccessPermission> repositoryUsers = new ArrayList<UserAccessPermission>(); final List<TeamAccessPermission> repositoryTeams = new ArrayList<TeamAccessPermission>(); List<String> preReceiveScripts = new ArrayList<String>(); List<String> postReceiveScripts = new ArrayList<String>(); @@ -128,8 +134,8 @@ } else { super.setupPage(getString("gb.edit"), repositoryModel.name); if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)) { repositoryUsers.addAll(GitBlit.self().getRepositoryUsers(repositoryModel)); repositoryTeams.addAll(GitBlit.self().getRepositoryTeams(repositoryModel)); repositoryUsers.addAll(GitBlit.self().getUserAccessPermissions(repositoryModel)); repositoryTeams.addAll(GitBlit.self().getTeamAccessPermissions(repositoryModel)); Collections.sort(repositoryUsers); } federationSets.addAll(repositoryModel.federationSets); @@ -139,15 +145,9 @@ } final String oldName = repositoryModel.name; // users palette final Palette<String> usersPalette = new Palette<String>("users", new ListModel<String>( repositoryUsers), new CollectionModel<String>(GitBlit.self().getAllUsernames()), new StringChoiceRenderer(), 10, false); // teams palette final Palette<String> teamsPalette = new Palette<String>("teams", new ListModel<String>( repositoryTeams), new CollectionModel<String>(GitBlit.self().getAllTeamnames()), new StringChoiceRenderer(), 8, false); UserPermissionsPanel usersPalette = new UserPermissionsPanel("users", repositoryUsers, getAccessPermissions()); TeamPermissionsPanel teamsPalette = new TeamPermissionsPanel("teams", repositoryTeams, getAccessPermissions()); // indexed local branches palette List<String> allLocalBranches = new ArrayList<String>(); @@ -342,28 +342,10 @@ // save the repository GitBlit.self().updateRepositoryModel(oldName, repositoryModel, isCreate); // repository access // repository access permissions if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)) { // save the user access list Iterator<String> users = usersPalette.getSelectedChoices(); List<String> repositoryUsers = new ArrayList<String>(); while (users.hasNext()) { repositoryUsers.add(users.next()); } // ensure the owner is added to the user list if (repositoryModel.owner != null && !repositoryUsers.contains(repositoryModel.owner)) { repositoryUsers.add(repositoryModel.owner); } GitBlit.self().setRepositoryUsers(repositoryModel, repositoryUsers); // save the team access list Iterator<String> teams = teamsPalette.getSelectedChoices(); List<String> repositoryTeams = new ArrayList<String>(); while (teams.hasNext()) { repositoryTeams.add(teams.next()); } GitBlit.self().setRepositoryTeams(repositoryModel, repositoryTeams); GitBlit.self().setUserAccessPermissions(repositoryModel, repositoryUsers); GitBlit.self().setTeamAccessPermissions(repositoryModel, repositoryTeams); } } catch (GitBlitException e) { error(e.getMessage()); src/com/gitblit/wicket/panels/TeamPermissionsPanel.html
New file @@ -0,0 +1,24 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd" xml:lang="en" lang="en"> <body> <wicket:panel> <div wicket:id="permissionRow"> <div style="padding-top:10px" class="row-fluid"> <span class="span8" wicket:id="team"></span> <select class="input-medium" wicket:id="permission"></select> </div> </div> <div style="padding-top:15px;" class="row-fluid"> <form class="well form-inline" wicket:id="addPermissionForm"> <select class="input-large" wicket:id="team"></select> <select class="input-medium" wicket:id="permission"></select> <input class="btn btn-success" type="submit" value="Add" wicket:message="value:gb.add" wicket:id="addPermissionButton"/> </form> </div> </wicket:panel> </body> </html> src/com/gitblit/wicket/panels/TeamPermissionsPanel.java
New file @@ -0,0 +1,157 @@ /* * Copyright 2012 gitblit.com. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gitblit.wicket.panels; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.IChoiceRenderer; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.OddEvenItem; import org.apache.wicket.markup.repeater.RefreshingView; import org.apache.wicket.markup.repeater.util.ModelIteratorAdapter; import org.apache.wicket.model.CompoundPropertyModel; import org.apache.wicket.model.IModel; import com.gitblit.Constants.AccessPermission; import com.gitblit.GitBlit; import com.gitblit.models.TeamAccessPermission; import com.gitblit.utils.DeepCopier; /** * Allows user to manipulate user access permissions. * * @author James Moger * */ public class TeamPermissionsPanel extends BasePanel { private static final long serialVersionUID = 1L; public TeamPermissionsPanel(String wicketId, final List<TeamAccessPermission> permissions, final Map<AccessPermission, String> translations) { super(wicketId); // update existing permissions repeater RefreshingView<TeamAccessPermission> dataView = new RefreshingView<TeamAccessPermission>("permissionRow") { private static final long serialVersionUID = 1L; @Override protected Iterator<IModel<TeamAccessPermission>> getItemModels() { // the iterator returns RepositoryPermission objects, but we need it to // return models return new ModelIteratorAdapter<TeamAccessPermission>(permissions.iterator()) { @Override protected IModel<TeamAccessPermission> model(TeamAccessPermission permission) { return new CompoundPropertyModel<TeamAccessPermission>(permission); } }; } @Override protected Item<TeamAccessPermission> newItem(String id, int index, IModel<TeamAccessPermission> model) { // this item sets markup class attribute to either 'odd' or // 'even' for decoration return new OddEvenItem<TeamAccessPermission>(id, index, model); } public void populateItem(final Item<TeamAccessPermission> item) { final TeamAccessPermission entry = item.getModelObject(); item.add(new Label("team", entry.team)); // use ajax to get immediate update of permission level change // otherwise we can lose it if they change levels and then add // a new repository permission final DropDownChoice<AccessPermission> permissionChoice = new DropDownChoice<AccessPermission>( "permission", Arrays.asList(AccessPermission.values()), new AccessPermissionRenderer(translations)); permissionChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") { private static final long serialVersionUID = 1L; protected void onUpdate(AjaxRequestTarget target) { target.addComponent(permissionChoice); } }); item.add(permissionChoice); } }; add(dataView); setOutputMarkupId(true); // filter out teams we already have permissions for final List<String> teams = GitBlit.self().getAllTeamnames(); for (TeamAccessPermission tp : permissions) { teams.remove(tp.team); } // add new permission form IModel<TeamAccessPermission> addPermissionModel = new CompoundPropertyModel<TeamAccessPermission>(new TeamAccessPermission()); Form<TeamAccessPermission> addPermissionForm = new Form<TeamAccessPermission>("addPermissionForm", addPermissionModel); addPermissionForm.add(new DropDownChoice<String>("team", teams)); addPermissionForm.add(new DropDownChoice<AccessPermission>("permission", Arrays .asList(AccessPermission.NEWPERMISSIONS), new AccessPermissionRenderer(translations))); AjaxButton button = new AjaxButton("addPermissionButton", addPermissionForm) { private static final long serialVersionUID = 1L; @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { // add permission to our list TeamAccessPermission tp = (TeamAccessPermission) form.getModel().getObject(); permissions.add(DeepCopier.copy(tp)); // remove team from available choices teams.remove(tp.team); // force the panel to refresh target.addComponent(TeamPermissionsPanel.this); } }; addPermissionForm.add(button); // only show add permission form if we have a team choice add(addPermissionForm.setVisible(teams.size() > 0)); } private class AccessPermissionRenderer implements IChoiceRenderer<AccessPermission> { private static final long serialVersionUID = 1L; private final Map<AccessPermission, String> map; public AccessPermissionRenderer(Map<AccessPermission, String> map) { this.map = map; } @Override public String getDisplayValue(AccessPermission type) { return map.get(type); } @Override public String getIdValue(AccessPermission type, int index) { return Integer.toString(index); } } } src/com/gitblit/wicket/panels/UserPermissionsPanel.html
New file @@ -0,0 +1,24 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd" xml:lang="en" lang="en"> <body> <wicket:panel> <div wicket:id="permissionRow"> <div style="padding-top:10px" class="row-fluid"> <span class="span8" wicket:id="user"></span> <select class="input-medium" wicket:id="permission"></select> </div> </div> <div style="padding-top:15px;" class="row-fluid"> <form class="well form-inline" wicket:id="addPermissionForm"> <select class="input-large" wicket:id="user"></select> <select class="input-medium" wicket:id="permission"></select> <input class="btn btn-success" type="submit" value="Add" wicket:message="value:gb.add" wicket:id="addPermissionButton"/> </form> </div> </wicket:panel> </body> </html> src/com/gitblit/wicket/panels/UserPermissionsPanel.java
New file @@ -0,0 +1,157 @@ /* * Copyright 2012 gitblit.com. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gitblit.wicket.panels; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.IChoiceRenderer; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.OddEvenItem; import org.apache.wicket.markup.repeater.RefreshingView; import org.apache.wicket.markup.repeater.util.ModelIteratorAdapter; import org.apache.wicket.model.CompoundPropertyModel; import org.apache.wicket.model.IModel; import com.gitblit.Constants.AccessPermission; import com.gitblit.GitBlit; import com.gitblit.models.UserAccessPermission; import com.gitblit.utils.DeepCopier; /** * Allows user to manipulate user access permissions. * * @author James Moger * */ public class UserPermissionsPanel extends BasePanel { private static final long serialVersionUID = 1L; public UserPermissionsPanel(String wicketId, final List<UserAccessPermission> permissions, final Map<AccessPermission, String> translations) { super(wicketId); // update existing permissions repeater RefreshingView<UserAccessPermission> dataView = new RefreshingView<UserAccessPermission>("permissionRow") { private static final long serialVersionUID = 1L; @Override protected Iterator<IModel<UserAccessPermission>> getItemModels() { // the iterator returns RepositoryPermission objects, but we need it to // return models return new ModelIteratorAdapter<UserAccessPermission>(permissions.iterator()) { @Override protected IModel<UserAccessPermission> model(UserAccessPermission permission) { return new CompoundPropertyModel<UserAccessPermission>(permission); } }; } @Override protected Item<UserAccessPermission> newItem(String id, int index, IModel<UserAccessPermission> model) { // this item sets markup class attribute to either 'odd' or // 'even' for decoration return new OddEvenItem<UserAccessPermission>(id, index, model); } public void populateItem(final Item<UserAccessPermission> item) { final UserAccessPermission entry = item.getModelObject(); item.add(new Label("user", entry.user)); // use ajax to get immediate update of permission level change // otherwise we can lose it if they change levels and then add // a new repository permission final DropDownChoice<AccessPermission> permissionChoice = new DropDownChoice<AccessPermission>( "permission", Arrays.asList(AccessPermission.values()), new AccessPermissionRenderer(translations)); permissionChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") { private static final long serialVersionUID = 1L; protected void onUpdate(AjaxRequestTarget target) { target.addComponent(permissionChoice); } }); item.add(permissionChoice); } }; add(dataView); setOutputMarkupId(true); // filter out users we already have permissions for final List<String> users = GitBlit.self().getAllUsernames(); for (UserAccessPermission up : permissions) { users.remove(up.user); } // add new permission form IModel<UserAccessPermission> addPermissionModel = new CompoundPropertyModel<UserAccessPermission>(new UserAccessPermission()); Form<UserAccessPermission> addPermissionForm = new Form<UserAccessPermission>("addPermissionForm", addPermissionModel); addPermissionForm.add(new DropDownChoice<String>("user", users)); addPermissionForm.add(new DropDownChoice<AccessPermission>("permission", Arrays .asList(AccessPermission.NEWPERMISSIONS), new AccessPermissionRenderer(translations))); AjaxButton button = new AjaxButton("addPermissionButton", addPermissionForm) { private static final long serialVersionUID = 1L; @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { // add permission to our list UserAccessPermission up = (UserAccessPermission) form.getModel().getObject(); permissions.add(DeepCopier.copy(up)); // remove user from available choices users.remove(up.user); // force the panel to refresh target.addComponent(UserPermissionsPanel.this); } }; addPermissionForm.add(button); // only show add permission form if we have a user choice add(addPermissionForm.setVisible(users.size() > 0)); } private class AccessPermissionRenderer implements IChoiceRenderer<AccessPermission> { private static final long serialVersionUID = 1L; private final Map<AccessPermission, String> map; public AccessPermissionRenderer(Map<AccessPermission, String> map) { this.map = map; } @Override public String getDisplayValue(AccessPermission type) { return map.get(type); } @Override public String getIdValue(AccessPermission type, int index) { return Integer.toString(index); } } }