James Moger
2011-10-17 e15f9571998d247df3715202abb84cd54a0d46bc
commit | author | age
19c634 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  */
16 package com.gitblit.client;
17
18 import java.awt.BorderLayout;
841651 19 import java.awt.Color;
19c634 20 import java.awt.Component;
841651 21 import java.awt.Desktop;
JM 22 import java.awt.Insets;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
e15f95 25 import java.awt.event.KeyAdapter;
JM 26 import java.awt.event.KeyEvent;
19c634 27 import java.io.IOException;
841651 28 import java.net.URI;
JM 29 import java.text.MessageFormat;
30 import java.util.ArrayList;
31 import java.util.List;
19c634 32
841651 33 import javax.swing.JButton;
JM 34 import javax.swing.JLabel;
da0269 35 import javax.swing.JOptionPane;
19c634 36 import javax.swing.JPanel;
JM 37 import javax.swing.JScrollPane;
38 import javax.swing.JTabbedPane;
39 import javax.swing.JTable;
841651 40 import javax.swing.JTextField;
JM 41 import javax.swing.RowFilter;
42 import javax.swing.SwingConstants;
43 import javax.swing.event.ListSelectionEvent;
44 import javax.swing.event.ListSelectionListener;
45 import javax.swing.table.DefaultTableCellRenderer;
19c634 46 import javax.swing.table.TableCellRenderer;
841651 47 import javax.swing.table.TableRowSorter;
19c634 48
da0269 49 import com.gitblit.Constants.RpcRequest;
841651 50 import com.gitblit.client.ClosableTabComponent.CloseTabListener;
19c634 51 import com.gitblit.models.RepositoryModel;
841651 52 import com.gitblit.models.UserModel;
JM 53 import com.gitblit.utils.StringUtils;
19c634 54
841651 55 /**
JM 56  * GitblitPanel performs the login, all business logic, and contains all widgets
57  * to represent the state of a repository for the given account credentials.
58  * 
59  * @author James Moger
60  * 
61  */
62 public class GitblitPanel extends JPanel implements CloseTabListener {
19c634 63
JM 64     private static final long serialVersionUID = 1L;
65
841651 66     private final int margin = 5;
19c634 67
841651 68     private final Insets insets = new Insets(margin, margin, margin, margin);
JM 69
15a51d 70     private GitblitModel gitblit;
841651 71
JM 72     private JTabbedPane tabs;
19c634 73
JM 74     private JTable repositoriesTable;
841651 75
JM 76     private RepositoriesModel repositoriesModel;
77
4b430b 78     private JTable usersTable;
JM 79
80     private UsersModel usersModel;
841651 81
JM 82     private JButton createRepository;
83
84     private JButton delRepository;
85
86     private NameRenderer nameRenderer;
87
b7f591 88     private IndicatorsRenderer typeRenderer;
841651 89
JM 90     private DefaultTableCellRenderer ownerRenderer;
91
92     private DefaultTableCellRenderer sizeRenderer;
93
4b430b 94     private TableRowSorter<RepositoriesModel> defaultRepositoriesSorter;
JM 95
96     private TableRowSorter<UsersModel> defaultUsersSorter;
97
98     private JButton editRepository;
841651 99
JM 100     public GitblitPanel(GitblitRegistration reg) {
101         this(reg.url, reg.account, reg.password);
102     }
19c634 103
JM 104     public GitblitPanel(String url, String account, char[] password) {
15a51d 105         this.gitblit = new GitblitModel(url, account, password);
19c634 106
b7f591 107         final JButton browseRepository = new JButton(Translation.get("gb.browse"));
841651 108         browseRepository.setEnabled(false);
JM 109         browseRepository.addActionListener(new ActionListener() {
110             public void actionPerformed(ActionEvent e) {
111                 RepositoryModel model = getSelectedRepositories().get(0);
15a51d 112                 String u = MessageFormat.format("{0}/summary/{1}", gitblit.url,
841651 113                         StringUtils.encodeURL(model.name));
JM 114                 try {
115                     Desktop.getDesktop().browse(new URI(u));
116                 } catch (Exception x) {
117                     x.printStackTrace();
118                 }
119             }
120         });
19c634 121
b7f591 122         JButton refreshRepositories = new JButton(Translation.get("gb.refresh"));
da0269 123         refreshRepositories.addActionListener(new ActionListener() {
JM 124             public void actionPerformed(ActionEvent e) {
15a51d 125                 refreshRepositories();
da0269 126             }
JM 127         });
128
b7f591 129         createRepository = new JButton(Translation.get("gb.create"));
841651 130         createRepository.addActionListener(new ActionListener() {
JM 131             public void actionPerformed(ActionEvent e) {
da0269 132                 createRepository();
841651 133             }
JM 134         });
135
4b430b 136         editRepository = new JButton(Translation.get("gb.edit"));
841651 137         editRepository.setEnabled(false);
JM 138         editRepository.addActionListener(new ActionListener() {
139             public void actionPerformed(ActionEvent e) {
da0269 140                 editRepository(getSelectedRepositories().get(0));
841651 141             }
JM 142         });
143
b7f591 144         delRepository = new JButton(Translation.get("gb.delete"));
841651 145         delRepository.setEnabled(false);
JM 146         delRepository.addActionListener(new ActionListener() {
147             public void actionPerformed(ActionEvent e) {
da0269 148                 deleteRepositories(getSelectedRepositories());
841651 149             }
JM 150         });
151
da0269 152         nameRenderer = new NameRenderer();
b7f591 153         typeRenderer = new IndicatorsRenderer();
841651 154
JM 155         sizeRenderer = new DefaultTableCellRenderer();
156         sizeRenderer.setHorizontalAlignment(SwingConstants.RIGHT);
157         sizeRenderer.setForeground(new Color(0, 0x80, 0));
158
159         ownerRenderer = new DefaultTableCellRenderer();
160         ownerRenderer.setForeground(Color.gray);
161         ownerRenderer.setHorizontalAlignment(SwingConstants.CENTER);
162
163         repositoriesModel = new RepositoriesModel();
4b430b 164         defaultRepositoriesSorter = new TableRowSorter<RepositoriesModel>(repositoriesModel);
JM 165         repositoriesTable = Utils.newTable(repositoriesModel);
166         repositoriesTable.setRowHeight(nameRenderer.getFont().getSize() + 8);
167         repositoriesTable.setRowSorter(defaultRepositoriesSorter);
841651 168         repositoriesTable.getRowSorter().toggleSortOrder(RepositoriesModel.Columns.Name.ordinal());
JM 169
4b430b 170         setRepositoryRenderer(RepositoriesModel.Columns.Name, nameRenderer);
JM 171         setRepositoryRenderer(RepositoriesModel.Columns.Indicators, typeRenderer);
172         setRepositoryRenderer(RepositoriesModel.Columns.Owner, ownerRenderer);
173         setRepositoryRenderer(RepositoriesModel.Columns.Size, sizeRenderer);
841651 174
JM 175         repositoriesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
176             @Override
177             public void valueChanged(ListSelectionEvent e) {
178                 if (e.getValueIsAdjusting()) {
179                     return;
180                 }
181                 boolean singleSelection = repositoriesTable.getSelectedRowCount() == 1;
182                 boolean selected = repositoriesTable.getSelectedRow() > -1;
183                 browseRepository.setEnabled(singleSelection);
184                 delRepository.setEnabled(selected);
185                 if (selected) {
186                     int viewRow = repositoriesTable.getSelectedRow();
187                     int modelRow = repositoriesTable.convertRowIndexToModel(viewRow);
188                     RepositoryModel model = ((RepositoriesModel) repositoriesTable.getModel()).list
189                             .get(modelRow);
190                     editRepository.setEnabled(singleSelection
15a51d 191                             && (gitblit.allowAdmin() || gitblit.isOwner(model)));
841651 192                 } else {
JM 193                     editRepository.setEnabled(false);
194                 }
195             }
196         });
197
198         final JTextField repositoryFilter = new JTextField();
199         repositoryFilter.addActionListener(new ActionListener() {
200             public void actionPerformed(ActionEvent e) {
201                 filterRepositories(repositoryFilter.getText());
202             }
203         });
e15f95 204         repositoryFilter.addKeyListener(new KeyAdapter() {
JM 205             public void keyReleased(KeyEvent e) {
206                 filterRepositories(repositoryFilter.getText());
207             }
208         });
841651 209
e15f95 210         JPanel repositoryFilterPanel = new JPanel(new BorderLayout(margin, margin));
JM 211         repositoryFilterPanel.add(new JLabel(Translation.get("gb.filter")), BorderLayout.WEST);
212         repositoryFilterPanel.add(repositoryFilter, BorderLayout.CENTER);
841651 213
e15f95 214         JPanel repositoryTablePanel = new JPanel(new BorderLayout(margin, margin));
JM 215         repositoryTablePanel.add(repositoryFilterPanel, BorderLayout.NORTH);
216         repositoryTablePanel.add(new JScrollPane(repositoriesTable), BorderLayout.CENTER);
841651 217
JM 218         JPanel repositoryControls = new JPanel();
15a51d 219         repositoryControls.add(refreshRepositories);
841651 220         repositoryControls.add(browseRepository);
JM 221         repositoryControls.add(createRepository);
222         repositoryControls.add(editRepository);
223         repositoryControls.add(delRepository);
224
225         JPanel repositoriesPanel = new JPanel(new BorderLayout(margin, margin));
b7f591 226         repositoriesPanel.add(newHeaderLabel(Translation.get("gb.repositories")),
JM 227                 BorderLayout.NORTH);
e15f95 228         repositoriesPanel.add(repositoryTablePanel, BorderLayout.CENTER);
841651 229         repositoriesPanel.add(repositoryControls, BorderLayout.SOUTH);
JM 230
b7f591 231         JButton refreshUsers = new JButton(Translation.get("gb.refresh"));
da0269 232         refreshUsers.addActionListener(new ActionListener() {
JM 233             public void actionPerformed(ActionEvent e) {
15a51d 234                 refreshUsers();
da0269 235             }
JM 236         });
237
b7f591 238         JButton createUser = new JButton(Translation.get("gb.create"));
841651 239         createUser.addActionListener(new ActionListener() {
JM 240             public void actionPerformed(ActionEvent e) {
da0269 241                 createUser();
841651 242             }
JM 243         });
244
b7f591 245         final JButton editUser = new JButton(Translation.get("gb.edit"));
841651 246         editUser.setEnabled(false);
JM 247         editUser.addActionListener(new ActionListener() {
248             public void actionPerformed(ActionEvent e) {
da0269 249                 editUser(getSelectedUsers().get(0));
841651 250             }
JM 251         });
252
b7f591 253         final JButton delUser = new JButton(Translation.get("gb.delete"));
841651 254         delUser.setEnabled(false);
JM 255         delUser.addActionListener(new ActionListener() {
256             public void actionPerformed(ActionEvent e) {
da0269 257                 deleteUsers(getSelectedUsers());
841651 258             }
JM 259         });
260
4b430b 261         usersModel = new UsersModel();
JM 262         defaultUsersSorter = new TableRowSorter<UsersModel>(usersModel);
263         usersTable = Utils.newTable(usersModel);
264         String name = usersTable.getColumnName(UsersModel.Columns.Name.ordinal());
265         usersTable.setRowHeight(nameRenderer.getFont().getSize() + 8);
266         usersTable.getColumn(name).setCellRenderer(nameRenderer);
267         usersTable.setRowSorter(defaultUsersSorter);
268         usersTable.getRowSorter().toggleSortOrder(UsersModel.Columns.Name.ordinal());
269         usersTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
841651 270
JM 271             @Override
272             public void valueChanged(ListSelectionEvent e) {
273                 if (e.getValueIsAdjusting()) {
274                     return;
275                 }
4b430b 276                 boolean selected = usersTable.getSelectedRow() > -1;
JM 277                 boolean singleSelection = usersTable.getSelectedRows().length == 1;
841651 278                 editUser.setEnabled(singleSelection && selected);
JM 279                 delUser.setEnabled(selected);
280             }
281         });
282
e15f95 283         final JTextField userFilter = new JTextField();
JM 284         userFilter.addActionListener(new ActionListener() {
285             public void actionPerformed(ActionEvent e) {
286                 filterUsers(userFilter.getText());
287             }
288         });
289         userFilter.addKeyListener(new KeyAdapter() {
290             public void keyReleased(KeyEvent e) {
291                 filterUsers(userFilter.getText());
292             }
293         });
294
295         JPanel userFilterPanel = new JPanel(new BorderLayout(margin, margin));
296         userFilterPanel.add(new JLabel(Translation.get("gb.filter")), BorderLayout.WEST);
297         userFilterPanel.add(userFilter, BorderLayout.CENTER);
298
299         JPanel userTablePanel = new JPanel(new BorderLayout(margin, margin));
300         userTablePanel.add(userFilterPanel, BorderLayout.NORTH);
301         userTablePanel.add(new JScrollPane(usersTable), BorderLayout.CENTER);
302
4b430b 303         JPanel userControls = new JPanel();
da0269 304         userControls.add(refreshUsers);
841651 305         userControls.add(createUser);
JM 306         userControls.add(editUser);
307         userControls.add(delUser);
308
e15f95 309         JPanel usersPanel = new JPanel(new BorderLayout(margin, margin));
b7f591 310         usersPanel.add(newHeaderLabel(Translation.get("gb.users")), BorderLayout.NORTH);
e15f95 311         usersPanel.add(userTablePanel, BorderLayout.CENTER);
841651 312         usersPanel.add(userControls, BorderLayout.SOUTH);
JM 313
314         tabs = new JTabbedPane(JTabbedPane.BOTTOM);
4b430b 315         tabs.addTab(Translation.get("gb.repositories"), repositoriesPanel);
JM 316         tabs.addTab(Translation.get("gb.users"), usersPanel);
b7f591 317         tabs.addTab(Translation.get("gb.federation"), new JPanel());
19c634 318
JM 319         setLayout(new BorderLayout());
320         add(tabs, BorderLayout.CENTER);
321     }
322
841651 323     private JLabel newHeaderLabel(String text) {
JM 324         JLabel label = new JLabel(text);
325         label.setOpaque(true);
326         label.setForeground(Color.white);
327         label.setBackground(Color.gray);
328         label.setFont(label.getFont().deriveFont(14f));
329         return label;
330     }
331
4b430b 332     private void setRepositoryRenderer(RepositoriesModel.Columns col, TableCellRenderer renderer) {
15a51d 333         String name = repositoriesTable.getColumnName(col.ordinal());
JM 334         repositoriesTable.getColumn(name).setCellRenderer(renderer);
335     }
841651 336
15a51d 337     public void login() throws IOException {
JM 338         gitblit.login();
339
340         updateRepositoriesTable();
341         Utils.packColumns(repositoriesTable, 2);
342
343         if (gitblit.allowAdmin()) {
344             updateUsersTable();
345         } else {
841651 346             // user does not have administrator privileges
JM 347             // hide admin repository buttons
348             createRepository.setVisible(false);
4b430b 349             editRepository.setVisible(false);
841651 350             delRepository.setVisible(false);
JM 351
4b430b 352             while (tabs.getTabCount() > 1) {
JM 353                 // remove admin tabs
354                 tabs.removeTabAt(1);
355             }
841651 356         }
19c634 357     }
JM 358
15a51d 359     private void updateRepositoriesTable() {
841651 360         repositoriesModel.list.clear();
15a51d 361         repositoriesModel.list.addAll(gitblit.getRepositories());
841651 362         repositoriesModel.fireTableDataChanged();
JM 363     }
364
15a51d 365     private void updateUsersTable() {
4b430b 366         usersModel.list.clear();
JM 367         usersModel.list.addAll(gitblit.getUsers());
368         usersModel.fireTableDataChanged();
841651 369     }
JM 370
371     private void filterRepositories(final String fragment) {
372         if (StringUtils.isEmpty(fragment)) {
4b430b 373             repositoriesTable.setRowSorter(defaultRepositoriesSorter);
841651 374             return;
JM 375         }
376         RowFilter<RepositoriesModel, Object> containsFilter = new RowFilter<RepositoriesModel, Object>() {
377             public boolean include(Entry<? extends RepositoriesModel, ? extends Object> entry) {
378                 for (int i = entry.getValueCount() - 1; i >= 0; i--) {
379                     if (entry.getStringValue(i).toLowerCase().contains(fragment.toLowerCase())) {
380                         return true;
381                     }
382                 }
383                 return false;
384             }
385         };
e15f95 386         TableRowSorter<RepositoriesModel> sorter = new TableRowSorter<RepositoriesModel>(
JM 387                 repositoriesModel);
841651 388         sorter.setRowFilter(containsFilter);
JM 389         repositoriesTable.setRowSorter(sorter);
390     }
391
e15f95 392     private void filterUsers(final String fragment) {
JM 393         if (StringUtils.isEmpty(fragment)) {
394             usersTable.setRowSorter(defaultUsersSorter);
395             return;
396         }
397         RowFilter<UsersModel, Object> containsFilter = new RowFilter<UsersModel, Object>() {
398             public boolean include(Entry<? extends UsersModel, ? extends Object> entry) {
399                 for (int i = entry.getValueCount() - 1; i >= 0; i--) {
400                     if (entry.getStringValue(i).toLowerCase().contains(fragment.toLowerCase())) {
401                         return true;
402                     }
403                 }
404                 return false;
405             }
406         };
407         TableRowSorter<UsersModel> sorter = new TableRowSorter<UsersModel>(usersModel);
408         sorter.setRowFilter(containsFilter);
409         usersTable.setRowSorter(sorter);
410     }
411
841651 412     private List<RepositoryModel> getSelectedRepositories() {
JM 413         List<RepositoryModel> repositories = new ArrayList<RepositoryModel>();
414         for (int viewRow : repositoriesTable.getSelectedRows()) {
415             int modelRow = repositoriesTable.convertRowIndexToModel(viewRow);
4b430b 416             RepositoryModel model = repositoriesModel.list.get(modelRow);
841651 417             repositories.add(model);
JM 418         }
419         return repositories;
420     }
421
422     private List<UserModel> getSelectedUsers() {
423         List<UserModel> users = new ArrayList<UserModel>();
4b430b 424         for (int viewRow : usersTable.getSelectedRows()) {
JM 425             int modelRow = usersTable.convertRowIndexToModel(viewRow);
426             UserModel model = usersModel.list.get(modelRow);
841651 427             users.add(model);
JM 428         }
429         return users;
19c634 430     }
JM 431
841651 432     @Override
JM 433     public Insets getInsets() {
434         return insets;
435     }
436
437     @Override
438     public void closeTab(Component c) {
15a51d 439         gitblit = null;
JM 440     }
441
442     protected void refreshRepositories() {
443         GitblitWorker worker = new GitblitWorker(GitblitPanel.this, RpcRequest.LIST_REPOSITORIES) {
444             @Override
445             protected Boolean doRequest() throws IOException {
446                 gitblit.refreshRepositories();
447                 return true;
448             }
449
450             @Override
451             protected void onSuccess() {
452                 updateRepositoriesTable();
453             }
454         };
455         worker.execute();
841651 456     }
da0269 457
JM 458     /**
459      * Displays the create repository dialog and fires a SwingWorker to update
460      * the server, if appropriate.
461      * 
462      */
463     protected void createRepository() {
bcc616 464         EditRepositoryDialog dialog = new EditRepositoryDialog();
15a51d 465         dialog.setUsers(null, gitblit.getUsernames(), null);
JM 466         dialog.setRepositories(gitblit.getRepositories());
da0269 467         dialog.setVisible(true);
JM 468         final RepositoryModel newRepository = dialog.getRepository();
bcc616 469         final List<String> permittedUsers = dialog.getPermittedUsers();
da0269 470         if (newRepository == null) {
JM 471             return;
472         }
473
15a51d 474         GitblitWorker worker = new GitblitWorker(this, RpcRequest.CREATE_REPOSITORY) {
da0269 475
JM 476             @Override
15a51d 477             protected Boolean doRequest() throws IOException {
JM 478                 boolean success = gitblit.createRepository(newRepository, permittedUsers);
479                 if (success) {
480                     gitblit.refreshRepositories();
481                     if (permittedUsers.size() > 0) {
482                         gitblit.refreshUsers();
483                     }
bcc616 484                 }
JM 485                 return success;
da0269 486             }
JM 487
488             @Override
15a51d 489             protected void onSuccess() {
JM 490                 updateRepositoriesTable();
491                 updateUsersTable();
492             }
493
494             @Override
495             protected void onFailure() {
496                 showFailure("Failed to execute request \"{0}\" for repository \"{1}\".",
497                         getRequestType(), newRepository.name);
da0269 498             }
JM 499         };
500         worker.execute();
501     }
502
503     /**
504      * Displays the edit repository dialog and fires a SwingWorker to update the
505      * server, if appropriate.
506      * 
507      * @param repository
508      */
509     protected void editRepository(final RepositoryModel repository) {
bcc616 510         EditRepositoryDialog dialog = new EditRepositoryDialog(repository);
15a51d 511         List<String> usernames = gitblit.getUsernames();
JM 512         List<String> members = gitblit.getPermittedUsernames(repository);
bcc616 513         dialog.setUsers(repository.owner, usernames, members);
15a51d 514         dialog.setFederationSets(gitblit.getFederationSets(), repository.federationSets);
da0269 515         dialog.setVisible(true);
JM 516         final RepositoryModel revisedRepository = dialog.getRepository();
bcc616 517         final List<String> permittedUsers = dialog.getPermittedUsers();
da0269 518         if (revisedRepository == null) {
JM 519             return;
520         }
521
15a51d 522         GitblitWorker worker = new GitblitWorker(this, RpcRequest.EDIT_REPOSITORY) {
da0269 523
JM 524             @Override
15a51d 525             protected Boolean doRequest() throws IOException {
JM 526                 boolean success = gitblit.updateRepository(repository.name, revisedRepository,
527                         permittedUsers);
528                 if (success) {
529                     gitblit.refreshRepositories();
530                     gitblit.refreshUsers();
531                 }
bcc616 532                 return success;
da0269 533             }
JM 534
535             @Override
15a51d 536             protected void onSuccess() {
JM 537                 updateRepositoriesTable();
538                 updateUsersTable();
539             }
540
541             @Override
542             protected void onFailure() {
543                 showFailure("Failed to execute request \"{0}\" for repository \"{1}\".",
544                         getRequestType(), repository.name);
da0269 545             }
JM 546         };
547         worker.execute();
548     }
549
550     protected void deleteRepositories(final List<RepositoryModel> repositories) {
551         if (repositories == null || repositories.size() == 0) {
552             return;
553         }
554         StringBuilder message = new StringBuilder("Delete the following repositories?\n\n");
555         for (RepositoryModel repository : repositories) {
556             message.append(repository.name).append("\n");
557         }
558         int result = JOptionPane.showConfirmDialog(GitblitPanel.this, message.toString(),
559                 "Delete Repositories?", JOptionPane.YES_NO_OPTION);
560         if (result == JOptionPane.YES_OPTION) {
15a51d 561             GitblitWorker worker = new GitblitWorker(this, RpcRequest.DELETE_REPOSITORY) {
da0269 562                 @Override
15a51d 563                 protected Boolean doRequest() throws IOException {
da0269 564                     boolean success = true;
JM 565                     for (RepositoryModel repository : repositories) {
15a51d 566                         success &= gitblit.deleteRepository(repository);
JM 567                     }
568                     if (success) {
569                         gitblit.refreshUsers();
da0269 570                     }
JM 571                     return success;
572                 }
573
574                 @Override
15a51d 575                 protected void onSuccess() {
JM 576                     updateRepositoriesTable();
577                     updateUsersTable();
578                 }
579
580                 @Override
581                 protected void onFailure() {
582                     showFailure("Failed to delete specified repositories!");
da0269 583                 }
JM 584             };
585             worker.execute();
586         }
15a51d 587     }
JM 588
589     protected void refreshUsers() {
590         GitblitWorker worker = new GitblitWorker(GitblitPanel.this, RpcRequest.LIST_USERS) {
591             @Override
592             protected Boolean doRequest() throws IOException {
593                 gitblit.refreshUsers();
594                 return true;
595             }
596
597             @Override
598             protected void onSuccess() {
599                 updateUsersTable();
600             }
601         };
602         worker.execute();
da0269 603     }
JM 604
605     /**
606      * Displays the create user dialog and fires a SwingWorker to update the
607      * server, if appropriate.
608      * 
609      */
610     protected void createUser() {
15a51d 611         EditUserDialog dialog = new EditUserDialog(gitblit.getSettings());
JM 612         dialog.setUsers(gitblit.getUsers());
613         dialog.setRepositories(gitblit.getRepositories(), null);
da0269 614         dialog.setVisible(true);
JM 615         final UserModel newUser = dialog.getUser();
616         if (newUser == null) {
617             return;
618         }
619
15a51d 620         GitblitWorker worker = new GitblitWorker(this, RpcRequest.CREATE_USER) {
da0269 621
JM 622             @Override
15a51d 623             protected Boolean doRequest() throws IOException {
JM 624                 boolean success = gitblit.createUser(newUser);
625                 if (success) {
626                     gitblit.refreshUsers();
627                 }
628                 return success;
da0269 629             }
JM 630
631             @Override
15a51d 632             protected void onSuccess() {
JM 633                 updateUsersTable();
634             }
635
636             @Override
637             protected void onFailure() {
638                 showFailure("Failed to execute request \"{0}\" for user \"{1}\".",
639                         getRequestType(), newUser.username);
da0269 640             }
JM 641         };
642         worker.execute();
643     }
644
645     /**
646      * Displays the edit user dialog and fires a SwingWorker to update the
647      * server, if appropriate.
648      * 
649      * @param user
650      */
651     protected void editUser(final UserModel user) {
15a51d 652         EditUserDialog dialog = new EditUserDialog(user, gitblit.getSettings());
JM 653         dialog.setRepositories(gitblit.getRepositories(), new ArrayList<String>(user.repositories));
da0269 654         dialog.setVisible(true);
JM 655         final UserModel revisedUser = dialog.getUser();
656         if (revisedUser == null) {
657             return;
658         }
659
15a51d 660         GitblitWorker worker = new GitblitWorker(this, RpcRequest.EDIT_USER) {
da0269 661             @Override
15a51d 662             protected Boolean doRequest() throws IOException {
JM 663                 boolean success = gitblit.updateUser(user.username, revisedUser);
664                 if (success) {
665                     gitblit.refreshUsers();
666                 }
667                 return success;
da0269 668             }
JM 669
670             @Override
15a51d 671             protected void onSuccess() {
JM 672                 updateUsersTable();
673             }
674
675             @Override
676             protected void onFailure() {
677                 showFailure("Failed to execute request \"{0}\" for user \"{1}\".",
678                         getRequestType(), user.username);
da0269 679             }
JM 680         };
681         worker.execute();
682     }
683
684     protected void deleteUsers(final List<UserModel> users) {
685         if (users == null || users.size() == 0) {
686             return;
687         }
688         StringBuilder message = new StringBuilder("Delete the following users?\n\n");
689         for (UserModel user : users) {
690             message.append(user.username).append("\n");
691         }
692         int result = JOptionPane.showConfirmDialog(GitblitPanel.this, message.toString(),
693                 "Delete Users?", JOptionPane.YES_NO_OPTION);
694         if (result == JOptionPane.YES_OPTION) {
15a51d 695             GitblitWorker worker = new GitblitWorker(this, RpcRequest.DELETE_USER) {
da0269 696                 @Override
15a51d 697                 protected Boolean doRequest() throws IOException {
da0269 698                     boolean success = true;
JM 699                     for (UserModel user : users) {
15a51d 700                         success &= gitblit.deleteUser(user);
JM 701                     }
702                     if (success) {
703                         gitblit.refreshUsers();
da0269 704                     }
JM 705                     return success;
706                 }
707
708                 @Override
15a51d 709                 protected void onSuccess() {
JM 710                     updateUsersTable();
711                 }
712
713                 @Override
714                 protected void onFailure() {
715                     showFailure("Failed to delete specified users!");
da0269 716                 }
JM 717             };
718             worker.execute();
719         }
720     }
15a51d 721 }