James Moger
2012-09-10 fabe060d3a435f116128851f828e35c2af5fde67
commit | author | age
f13c4c 1 /*
JM 2  * Copyright 2011 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
f5d0ad 16 package com.gitblit.wicket.pages;
JM 17
f98825 18 import java.text.MessageFormat;
JM 19 import java.util.ArrayList;
dfb889 20 import java.util.Arrays;
00afd7 21 import java.util.Collections;
eb96ea 22 import java.util.HashSet;
f98825 23 import java.util.Iterator;
7c1cdc 24 import java.util.LinkedHashMap;
f98825 25 import java.util.List;
JM 26 import java.util.Map;
eb96ea 27 import java.util.Set;
f5d0ad 28
JM 29 import org.apache.wicket.PageParameters;
d3ca1c 30 import org.apache.wicket.behavior.SimpleAttributeModifier;
f98825 31 import org.apache.wicket.extensions.markup.html.form.palette.Palette;
ef4a45 32 import org.apache.wicket.markup.html.WebMarkupContainer;
JC 33 import org.apache.wicket.markup.html.basic.Label;
331fbc 34 import org.apache.wicket.markup.html.form.Button;
f5d0ad 35 import org.apache.wicket.markup.html.form.CheckBox;
dfb889 36 import org.apache.wicket.markup.html.form.DropDownChoice;
f5d0ad 37 import org.apache.wicket.markup.html.form.Form;
f98825 38 import org.apache.wicket.markup.html.form.IChoiceRenderer;
6adf56 39 import org.apache.wicket.markup.html.form.Radio;
JM 40 import org.apache.wicket.markup.html.form.RadioGroup;
f5d0ad 41 import org.apache.wicket.markup.html.form.TextField;
ef4a45 42 import org.apache.wicket.markup.html.list.ListItem;
JC 43 import org.apache.wicket.markup.html.list.ListView;
f5d0ad 44 import org.apache.wicket.model.CompoundPropertyModel;
3a2c57 45 import org.apache.wicket.model.IModel;
JM 46 import org.apache.wicket.model.Model;
f98825 47 import org.apache.wicket.model.util.CollectionModel;
JM 48 import org.apache.wicket.model.util.ListModel;
f5d0ad 49
ef4a45 50 import com.gitblit.Constants;
dfb889 51 import com.gitblit.Constants.AccessRestrictionType;
6adf56 52 import com.gitblit.Constants.AuthorizationControl;
831469 53 import com.gitblit.Constants.FederationStrategy;
f5d0ad 54 import com.gitblit.GitBlit;
166e6a 55 import com.gitblit.GitBlitException;
00afd7 56 import com.gitblit.Keys;
1f9dae 57 import com.gitblit.models.RepositoryModel;
JM 58 import com.gitblit.models.UserModel;
0db5c4 59 import com.gitblit.utils.ArrayUtils;
f98825 60 import com.gitblit.utils.StringUtils;
00afd7 61 import com.gitblit.wicket.GitBlitWebSession;
6fa6ab 62 import com.gitblit.wicket.StringChoiceRenderer;
f5d0ad 63 import com.gitblit.wicket.WicketUtils;
0d013a 64 import com.gitblit.wicket.panels.BulletListPanel;
f5d0ad 65
d376ab 66 public class EditRepositoryPage extends RootSubPage {
f5d0ad 67
JM 68     private final boolean isCreate;
69
2a7306 70     private boolean isAdmin;
3a2c57 71
eb96ea 72     private IModel<String> mailingLists;
2a7306 73
f5d0ad 74     public EditRepositoryPage() {
JM 75         // create constructor
76         super();
77         isCreate = true;
94dcbd 78         RepositoryModel model = new RepositoryModel();
JM 79         String restriction = GitBlit.getString(Keys.git.defaultAccessRestriction, null);
80         model.accessRestriction = AccessRestrictionType.fromName(restriction);
6adf56 81         String authorization = GitBlit.getString(Keys.git.defaultAuthorizationControl, null);
JM 82         model.authorizationControl = AuthorizationControl.fromName(authorization);
94dcbd 83         setupPage(model);
f5d0ad 84     }
JM 85
86     public EditRepositoryPage(PageParameters params) {
87         // edit constructor
88         super(params);
89         isCreate = false;
1e8390 90         String name = WicketUtils.getRepositoryName(params);
f97bf0 91         RepositoryModel model = GitBlit.self().getRepositoryModel(name);
1e8390 92         setupPage(model);
f5d0ad 93     }
JM 94
f97bf0 95     protected void setupPage(final RepositoryModel repositoryModel) {
00afd7 96         // ensure this user can create or edit this repository
JM 97         checkPermissions(repositoryModel);
2a7306 98
40ca5c 99         List<String> indexedBranches = new ArrayList<String>();
8f73a7 100         List<String> federationSets = new ArrayList<String>();
f98825 101         List<String> repositoryUsers = new ArrayList<String>();
fe24a0 102         List<String> repositoryTeams = new ArrayList<String>();
6cc1d4 103         List<String> preReceiveScripts = new ArrayList<String>();
JM 104         List<String> postReceiveScripts = new ArrayList<String>();
105
f5d0ad 106         if (isCreate) {
a7571b 107             super.setupPage(getString("gb.newRepository"), "");
f5d0ad 108         } else {
a7571b 109             super.setupPage(getString("gb.edit"), repositoryModel.name);
f98825 110             if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)) {
JM 111                 repositoryUsers.addAll(GitBlit.self().getRepositoryUsers(repositoryModel));
fe24a0 112                 repositoryTeams.addAll(GitBlit.self().getRepositoryTeams(repositoryModel));
00afd7 113                 Collections.sort(repositoryUsers);
f98825 114             }
8f73a7 115             federationSets.addAll(repositoryModel.federationSets);
40ca5c 116             if (!ArrayUtils.isEmpty(repositoryModel.indexedBranches)) {
JM 117                 indexedBranches.addAll(repositoryModel.indexedBranches);
118             }
3a2c57 119         }
f98825 120
8a2e9c 121         final String oldName = repositoryModel.name;
8f73a7 122         // users palette
2a7306 123         final Palette<String> usersPalette = new Palette<String>("users", new ListModel<String>(
JM 124                 repositoryUsers), new CollectionModel<String>(GitBlit.self().getAllUsernames()),
6fa6ab 125                 new StringChoiceRenderer(), 10, false);
fe24a0 126
JM 127         // teams palette
128         final Palette<String> teamsPalette = new Palette<String>("teams", new ListModel<String>(
129                 repositoryTeams), new CollectionModel<String>(GitBlit.self().getAllTeamnames()),
40ca5c 130                 new StringChoiceRenderer(), 8, false);
8f73a7 131
40ca5c 132         // indexed local branches palette
1aabf0 133         List<String> allLocalBranches = new ArrayList<String>();
JM 134         allLocalBranches.add(Constants.DEFAULT_BRANCH);
135         allLocalBranches.addAll(repositoryModel.getLocalBranches());
7db092 136         boolean luceneEnabled = GitBlit.getBoolean(Keys.web.allowLuceneIndexing, true);
40ca5c 137         final Palette<String> indexedBranchesPalette = new Palette<String>("indexedBranches", new ListModel<String>(
JM 138                 indexedBranches), new CollectionModel<String>(allLocalBranches),
139                 new StringChoiceRenderer(), 8, false);
1aabf0 140         indexedBranchesPalette.setEnabled(luceneEnabled);
40ca5c 141         
8f73a7 142         // federation sets palette
JM 143         List<String> sets = GitBlit.getStrings(Keys.federation.sets);
144         final Palette<String> federationSetsPalette = new Palette<String>("federationSets",
145                 new ListModel<String>(federationSets), new CollectionModel<String>(sets),
40ca5c 146                 new StringChoiceRenderer(), 8, false);
6cc1d4 147
JM 148         // pre-receive palette
0db5c4 149         if (!ArrayUtils.isEmpty(repositoryModel.preReceiveScripts)) {
6cc1d4 150             preReceiveScripts.addAll(repositoryModel.preReceiveScripts);
JM 151         }
152         final Palette<String> preReceivePalette = new Palette<String>("preReceiveScripts",
153                 new ListModel<String>(preReceiveScripts), new CollectionModel<String>(GitBlit
d7905a 154                         .self().getPreReceiveScriptsUnused(repositoryModel)),
6fa6ab 155                 new StringChoiceRenderer(), 12, true);
6cc1d4 156
JM 157         // post-receive palette
0db5c4 158         if (!ArrayUtils.isEmpty(repositoryModel.postReceiveScripts)) {
6cc1d4 159             postReceiveScripts.addAll(repositoryModel.postReceiveScripts);
JM 160         }
161         final Palette<String> postReceivePalette = new Palette<String>("postReceiveScripts",
162                 new ListModel<String>(postReceiveScripts), new CollectionModel<String>(GitBlit
d7905a 163                         .self().getPostReceiveScriptsUnused(repositoryModel)),
6fa6ab 164                 new StringChoiceRenderer(), 12, true);
ef4a45 165         
7c1cdc 166         // custom fields
JM 167         final Map<String, String> customFieldsMap = GitBlit.getMap(Keys.groovy.customFields);
168         List<String> customKeys = new ArrayList<String>(customFieldsMap.keySet());
169         final ListView<String> customFieldsListView = new ListView<String>("customFieldsListView", customKeys) {
170             
171             private static final long serialVersionUID = 1L;
172
ef4a45 173             @Override
7c1cdc 174             protected void populateItem(ListItem<String> item) {
JM 175                 String key = item.getModelObject();
176                 item.add(new Label("customFieldLabel", customFieldsMap.get(key)));
ef4a45 177                 
7c1cdc 178                 String value = "";
JM 179                 if (repositoryModel.customFields != null && repositoryModel.customFields.containsKey(key)) {
180                     value = repositoryModel.customFields.get(key);
181                 }
182                 TextField<String> field = new TextField<String>("customFieldValue", new Model<String>(value));
183                 item.add(field);
ef4a45 184             }
JC 185         };
08d86d 186         customFieldsListView.setReuseItems(true);
8f73a7 187
2a7306 188         CompoundPropertyModel<RepositoryModel> model = new CompoundPropertyModel<RepositoryModel>(
JM 189                 repositoryModel);
f5d0ad 190         Form<RepositoryModel> form = new Form<RepositoryModel>("editForm", model) {
JM 191
192             private static final long serialVersionUID = 1L;
193
194             @Override
195             protected void onSubmit() {
166e6a 196                 try {
f98825 197                     // confirm a repository name was entered
JM 198                     if (StringUtils.isEmpty(repositoryModel.name)) {
6caa93 199                         error(getString("gb.pleaseSetRepositoryName"));
f98825 200                         return;
JM 201                     }
202
203                     // automatically convert backslashes to forward slashes
204                     repositoryModel.name = repositoryModel.name.replace('\\', '/');
a125cf 205                     // Automatically replace // with /
JM 206                     repositoryModel.name = repositoryModel.name.replace("//", "/");
207
208                     // prohibit folder paths
008322 209                     if (repositoryModel.name.startsWith("/")) {
6caa93 210                         error(getString("gb.illegalLeadingSlash"));
a125cf 211                         return;
JM 212                     }
008322 213                     if (repositoryModel.name.startsWith("../")) {
6caa93 214                         error(getString("gb.illegalRelativeSlash"));
a125cf 215                         return;
JM 216                     }
217                     if (repositoryModel.name.contains("/../")) {
6caa93 218                         error(getString("gb.illegalRelativeSlash"));
a125cf 219                         return;
3fb41f 220                     }                    
JM 221                     if (repositoryModel.name.endsWith("/")) {
222                         repositoryModel.name = repositoryModel.name.substring(0, repositoryModel.name.length() - 1);
a125cf 223                     }
f98825 224
JM 225                     // confirm valid characters in repository name
831469 226                     Character c = StringUtils.findInvalidCharacter(repositoryModel.name);
JM 227                     if (c != null) {
6caa93 228                         error(MessageFormat.format(getString("gb.illegalCharacterRepositoryName"),
831469 229                                 c));
JM 230                         return;
f98825 231                     }
008322 232
f98825 233                     // confirm access restriction selection
JM 234                     if (repositoryModel.accessRestriction == null) {
6caa93 235                         error(getString("gb.selectAccessRestriction"));
f98825 236                         return;
JM 237                     }
00afd7 238
bcc616 239                     // confirm federation strategy selection
JM 240                     if (repositoryModel.federationStrategy == null) {
6caa93 241                         error(getString("gb.selectFederationStrategy"));
bcc616 242                         return;
JM 243                     }
244
8f73a7 245                     // save federation set preferences
JM 246                     if (repositoryModel.federationStrategy.exceeds(FederationStrategy.EXCLUDE)) {
247                         repositoryModel.federationSets.clear();
248                         Iterator<String> sets = federationSetsPalette.getSelectedChoices();
249                         while (sets.hasNext()) {
250                             repositoryModel.federationSets.add(sets.next());
251                         }
252                     }
253
eb96ea 254                     // set mailing lists
JM 255                     String ml = mailingLists.getObject();
3a2c57 256                     if (!StringUtils.isEmpty(ml)) {
eb96ea 257                         Set<String> list = new HashSet<String>();
JM 258                         for (String address : ml.split("(,|\\s)")) {
259                             if (StringUtils.isEmpty(address)) {
260                                 continue;
261                             }
262                             list.add(address.toLowerCase());
263                         }
264                         repositoryModel.mailingLists = new ArrayList<String>(list);
3a2c57 265                     }
JM 266
40ca5c 267                     // indexed branches
JM 268                     List<String> indexedBranches = new ArrayList<String>();
269                     Iterator<String> branches = indexedBranchesPalette.getSelectedChoices();
270                     while (branches.hasNext()) {
271                         indexedBranches.add(branches.next());
272                     }
273                     repositoryModel.indexedBranches = indexedBranches;
274
6cc1d4 275                     // pre-receive scripts
JM 276                     List<String> preReceiveScripts = new ArrayList<String>();
277                     Iterator<String> pres = preReceivePalette.getSelectedChoices();
278                     while (pres.hasNext()) {
279                         preReceiveScripts.add(pres.next());
280                     }
281                     repositoryModel.preReceiveScripts = preReceiveScripts;
282
283                     // post-receive scripts
284                     List<String> postReceiveScripts = new ArrayList<String>();
285                     Iterator<String> post = postReceivePalette.getSelectedChoices();
286                     while (post.hasNext()) {
287                         postReceiveScripts.add(post.next());
288                     }
289                     repositoryModel.postReceiveScripts = postReceiveScripts;
ef4a45 290                     
7c1cdc 291                     // custom fields
JM 292                     repositoryModel.customFields = new LinkedHashMap<String, String>();
08d86d 293                     for (int i = 0; i < customFieldsListView.size(); i++) {
7c1cdc 294                         ListItem<String> child = (ListItem<String>) customFieldsListView.get(i);
JM 295                         String key = child.getModelObject();
296
297                         TextField<String> field = (TextField<String>) child.get("customFieldValue");
298                         String value = field.getValue();
ef4a45 299                         
08d86d 300                         repositoryModel.customFields.put(key, value);
ef4a45 301                     }
JC 302                     
f98825 303                     // save the repository
892570 304                     GitBlit.self().updateRepositoryModel(oldName, repositoryModel, isCreate);
00afd7 305
fe24a0 306                     // repository access
f98825 307                     if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)) {
fe24a0 308                         // save the user access list
f98825 309                         Iterator<String> users = usersPalette.getSelectedChoices();
JM 310                         List<String> repositoryUsers = new ArrayList<String>();
311                         while (users.hasNext()) {
312                             repositoryUsers.add(users.next());
00afd7 313                         }
JM 314                         // ensure the owner is added to the user list
2a7306 315                         if (repositoryModel.owner != null
JM 316                                 && !repositoryUsers.contains(repositoryModel.owner)) {
00afd7 317                             repositoryUsers.add(repositoryModel.owner);
f98825 318                         }
JM 319                         GitBlit.self().setRepositoryUsers(repositoryModel, repositoryUsers);
3a2c57 320
fe24a0 321                         // save the team access list
JM 322                         Iterator<String> teams = teamsPalette.getSelectedChoices();
323                         List<String> repositoryTeams = new ArrayList<String>();
324                         while (teams.hasNext()) {
325                             repositoryTeams.add(teams.next());
326                         }
327                         GitBlit.self().setRepositoryTeams(repositoryModel, repositoryTeams);
f98825 328                     }
166e6a 329                 } catch (GitBlitException e) {
JM 330                     error(e.getMessage());
331                     return;
332                 }
a098da 333                 setRedirect(false);
f5d0ad 334                 setResponsePage(RepositoriesPage.class);
JM 335             }
336         };
dfb889 337
d3ca1c 338         // do not let the browser pre-populate these fields
JM 339         form.add(new SimpleAttributeModifier("autocomplete", "off"));
340
f97bf0 341         // field names reflective match RepositoryModel fields
8a2e9c 342         form.add(new TextField<String>("name").setEnabled(isCreate || isAdmin));
f5d0ad 343         form.add(new TextField<String>("description"));
2a7306 344         form.add(new DropDownChoice<String>("owner", GitBlit.self().getAllUsernames())
JM 345                 .setEnabled(GitBlitWebSession.get().canAdmin()));
346         form.add(new DropDownChoice<AccessRestrictionType>("accessRestriction", Arrays
347                 .asList(AccessRestrictionType.values()), new AccessRestrictionRenderer()));
00afd7 348         form.add(new CheckBox("isFrozen"));
831469 349         // TODO enable origin definition
8f73a7 350         form.add(new TextField<String>("origin").setEnabled(false/* isCreate */));
ddbf67 351         
JM 352         // allow relinking HEAD to a branch or tag other than master on edit repository
90b8d7 353         List<String> availableRefs = new ArrayList<String>();
JM 354         if (!ArrayUtils.isEmpty(repositoryModel.availableRefs)) {
355             availableRefs.addAll(repositoryModel.availableRefs);
ddbf67 356         }
6cbe89 357         form.add(new DropDownChoice<String>("HEAD", availableRefs).setEnabled(availableRefs.size() > 0));
8f73a7 358
831469 359         // federation strategies - remove ORIGIN choice if this repository has
JM 360         // no origin.
361         List<FederationStrategy> federationStrategies = new ArrayList<FederationStrategy>(
362                 Arrays.asList(FederationStrategy.values()));
363         if (StringUtils.isEmpty(repositoryModel.origin)) {
364             federationStrategies.remove(FederationStrategy.FEDERATE_ORIGIN);
365         }
366         form.add(new DropDownChoice<FederationStrategy>("federationStrategy", federationStrategies,
367                 new FederationTypeRenderer()));
f5d0ad 368         form.add(new CheckBox("useTickets"));
40ca5c 369         form.add(new CheckBox("useDocs"));        
cf9550 370         form.add(new CheckBox("showRemoteBranches"));
a1ea87 371         form.add(new CheckBox("showReadme"));
3d293a 372         form.add(new CheckBox("skipSizeCalculation"));
fe3262 373         form.add(new CheckBox("skipSummaryMetrics"));
0db5c4 374         mailingLists = new Model<String>(ArrayUtils.isEmpty(repositoryModel.mailingLists) ? ""
eb96ea 375                 : StringUtils.flattenStrings(repositoryModel.mailingLists, " "));
JM 376         form.add(new TextField<String>("mailingLists", mailingLists));
40ca5c 377         form.add(indexedBranchesPalette);
6adf56 378         
JM 379         RadioGroup<AuthorizationControl> group = new RadioGroup<AuthorizationControl>("authorizationControl");
380         Radio<AuthorizationControl> allowAuthenticated = new Radio<AuthorizationControl>("allowAuthenticated", new Model<AuthorizationControl>(AuthorizationControl.AUTHENTICATED));        
381         Radio<AuthorizationControl> allowNamed = new Radio<AuthorizationControl>("allowNamed", new Model<AuthorizationControl>(AuthorizationControl.NAMED));
382         group.add(allowAuthenticated);
383         group.add(allowNamed);
384         form.add(group);
385                 
f98825 386         form.add(usersPalette);
fe24a0 387         form.add(teamsPalette);
8f73a7 388         form.add(federationSetsPalette);
6cc1d4 389         form.add(preReceivePalette);
017749 390         form.add(new BulletListPanel("inheritedPreReceive", getString("gb.inherited"), GitBlit.self()
d7905a 391                 .getPreReceiveScriptsInherited(repositoryModel)));
6cc1d4 392         form.add(postReceivePalette);
017749 393         form.add(new BulletListPanel("inheritedPostReceive", getString("gb.inherited"), GitBlit.self()
d7905a 394                 .getPostReceiveScriptsInherited(repositoryModel)));
ef4a45 395         
7c1cdc 396         WebMarkupContainer customFieldsSection = new WebMarkupContainer("customFieldsSection");
JM 397         customFieldsSection.add(customFieldsListView);
398         form.add(customFieldsSection.setVisible(!GitBlit.getString(Keys.groovy.customFields, "").isEmpty()));
f5d0ad 399
719798 400         form.add(new Button("save"));
JM 401         Button cancel = new Button("cancel") {
331fbc 402             private static final long serialVersionUID = 1L;
JM 403
404             @Override
405             public void onSubmit() {
88598b 406                 setResponsePage(RepositoriesPage.class);
JM 407             }
408         };
409         cancel.setDefaultFormProcessing(false);
410         form.add(cancel);
411
f5d0ad 412         add(form);
JM 413     }
2a7306 414
00afd7 415     /**
JM 416      * Unfortunately must repeat part of AuthorizaitonStrategy here because that
417      * mechanism does not take PageParameters into consideration, only page
418      * instantiation.
419      * 
420      * Repository Owners should be able to edit their repository.
421      */
422     private void checkPermissions(RepositoryModel model) {
2a7306 423         boolean authenticateAdmin = GitBlit.getBoolean(Keys.web.authenticateAdminPages, true);
JM 424         boolean allowAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, true);
00afd7 425
JM 426         GitBlitWebSession session = GitBlitWebSession.get();
427         UserModel user = session.getUser();
428
429         if (allowAdmin) {
430             if (authenticateAdmin) {
431                 if (user == null) {
432                     // No Login Available
017749 433                     error(getString("gb.errorAdminLoginRequired"), true);
00afd7 434                 }
JM 435                 if (isCreate) {
436                     // Create Repository
2a7306 437                     if (!user.canAdmin) {
00afd7 438                         // Only Administrators May Create
017749 439                         error(getString("gb.errorOnlyAdminMayCreateRepository"), true);
00afd7 440                     }
JM 441                 } else {
442                     // Edit Repository
2a7306 443                     if (user.canAdmin) {
00afd7 444                         // Admins can edit everything
8a2e9c 445                         isAdmin = true;
00afd7 446                         return;
JM 447                     } else {
2a7306 448                         if (!model.owner.equalsIgnoreCase(user.username)) {
00afd7 449                             // User is not an Admin nor Owner
017749 450                             error(getString("gb.errorOnlyAdminOrOwnerMayEditRepository"), true);
00afd7 451                         }
2a7306 452                     }
00afd7 453                 }
JM 454             }
455         } else {
456             // No Administration Permitted
017749 457             error(getString("gb.errorAdministrationDisabled"), true);
912938 458         }
PLM 459     }
460
f98825 461     private class AccessRestrictionRenderer implements IChoiceRenderer<AccessRestrictionType> {
JM 462
463         private static final long serialVersionUID = 1L;
464
465         private final Map<AccessRestrictionType, String> map;
466
467         public AccessRestrictionRenderer() {
468             map = getAccessRestrictions();
469         }
470
471         @Override
472         public String getDisplayValue(AccessRestrictionType type) {
473             return map.get(type);
474         }
475
476         @Override
477         public String getIdValue(AccessRestrictionType type, int index) {
478             return Integer.toString(index);
479         }
480     }
831469 481
JM 482     private class FederationTypeRenderer implements IChoiceRenderer<FederationStrategy> {
483
484         private static final long serialVersionUID = 1L;
485
486         private final Map<FederationStrategy, String> map;
487
488         public FederationTypeRenderer() {
489             map = getFederationTypes();
490         }
491
492         @Override
493         public String getDisplayValue(FederationStrategy type) {
494             return map.get(type);
495         }
496
497         @Override
498         public String getIdValue(FederationStrategy type, int index) {
499             return Integer.toString(index);
500         }
501     }
f5d0ad 502 }