James Moger
2012-10-22 eba89539a29deba954035056437279088c3e047b
commit | author | age
f08aab 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;
19 import java.awt.Dimension;
20 import java.awt.FlowLayout;
21 import java.awt.Font;
22 import java.awt.GridLayout;
23 import java.awt.Insets;
24 import java.awt.event.ActionEvent;
25 import java.awt.event.ActionListener;
26 import java.awt.event.KeyEvent;
27 import java.text.MessageFormat;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.HashSet;
31 import java.util.List;
32 import java.util.Set;
33
34 import javax.swing.ImageIcon;
35 import javax.swing.JButton;
476269 36 import javax.swing.JCheckBox;
f08aab 37 import javax.swing.JComponent;
JM 38 import javax.swing.JDialog;
39 import javax.swing.JLabel;
40 import javax.swing.JOptionPane;
41 import javax.swing.JPanel;
42 import javax.swing.JRootPane;
43 import javax.swing.JTabbedPane;
44 import javax.swing.JTextField;
45 import javax.swing.KeyStroke;
46
47 import com.gitblit.Constants.AccessRestrictionType;
822dfe 48 import com.gitblit.models.RegistrantAccessPermission;
f08aab 49 import com.gitblit.models.RepositoryModel;
JM 50 import com.gitblit.models.ServerSettings;
51 import com.gitblit.models.TeamModel;
ba5424 52 import com.gitblit.utils.ArrayUtils;
f08aab 53 import com.gitblit.utils.StringUtils;
JM 54
55 public class EditTeamDialog extends JDialog {
56
57     private static final long serialVersionUID = 1L;
58
59     private final String teamname;
60
61     private final TeamModel team;
62
63     private final ServerSettings settings;
64
65     private boolean isCreate;
66
67     private boolean canceled = true;
68
69     private JTextField teamnameField;
476269 70     
JM 71     private JCheckBox canAdminCheckbox;
72     
73     private JCheckBox canForkCheckbox;
74     
75     private JCheckBox canCreateCheckbox;
f08aab 76
0b9119 77     private JTextField mailingListsField;
JM 78
822dfe 79     private RegistrantPermissionsPanel repositoryPalette;
f08aab 80
JM 81     private JPalette<String> userPalette;
82
97d3af 83     private JPalette<String> preReceivePalette;
JM 84
f2dff4 85     private JLabel preReceiveInherited;
JM 86
97d3af 87     private JPalette<String> postReceivePalette;
f2dff4 88
JM 89     private JLabel postReceiveInherited;
97d3af 90
f08aab 91     private Set<String> teamnames;
JM 92
93     public EditTeamDialog(int protocolVersion, ServerSettings settings) {
94         this(protocolVersion, new TeamModel(""), settings);
95         this.isCreate = true;
96         setTitle(Translation.get("gb.newTeam"));
97     }
98
99     public EditTeamDialog(int protocolVersion, TeamModel aTeam, ServerSettings settings) {
100         super();
101         this.teamname = aTeam.name;
102         this.team = new TeamModel("");
103         this.settings = settings;
104         this.teamnames = new HashSet<String>();
105         this.isCreate = false;
106         initialize(protocolVersion, aTeam);
107         setModal(true);
108         setTitle(Translation.get("gb.edit") + ": " + aTeam.name);
109         setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage());
110     }
111
112     @Override
113     protected JRootPane createRootPane() {
114         KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
115         JRootPane rootPane = new JRootPane();
116         rootPane.registerKeyboardAction(new ActionListener() {
117             public void actionPerformed(ActionEvent actionEvent) {
118                 setVisible(false);
119             }
120         }, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
121         return rootPane;
122     }
123
124     private void initialize(int protocolVersion, TeamModel aTeam) {
125         teamnameField = new JTextField(aTeam.name == null ? "" : aTeam.name, 25);
126
476269 127         canAdminCheckbox = new JCheckBox(Translation.get("gb.canAdminDescription"), aTeam.canAdmin);        
JM 128         canForkCheckbox = new JCheckBox(Translation.get("gb.canForkDescription"), aTeam.canFork);
129         canCreateCheckbox = new JCheckBox(Translation.get("gb.canCreateDescription"), aTeam.canCreate);
130
0b9119 131         mailingListsField = new JTextField(aTeam.mailingLists == null ? ""
JM 132                 : StringUtils.flattenStrings(aTeam.mailingLists, " "), 50);
133
f08aab 134         JPanel fieldsPanel = new JPanel(new GridLayout(0, 1));
JM 135         fieldsPanel.add(newFieldPanel(Translation.get("gb.teamName"), teamnameField));
476269 136         fieldsPanel.add(newFieldPanel(Translation.get("gb.canAdmin"), canAdminCheckbox));
JM 137         fieldsPanel.add(newFieldPanel(Translation.get("gb.canFork"), canForkCheckbox));
138         fieldsPanel.add(newFieldPanel(Translation.get("gb.canCreate"), canCreateCheckbox));
139
0b9119 140         fieldsPanel.add(newFieldPanel(Translation.get("gb.mailingLists"), mailingListsField));
f08aab 141
JM 142         final Insets _insets = new Insets(5, 5, 5, 5);
822dfe 143         repositoryPalette = new RegistrantPermissionsPanel();
f08aab 144         userPalette = new JPalette<String>();
e19110 145         userPalette.setEnabled(settings.supportsTeamMembershipChanges);
JM 146         
f08aab 147         JPanel fieldsPanelTop = new JPanel(new BorderLayout());
JM 148         fieldsPanelTop.add(fieldsPanel, BorderLayout.NORTH);
0b9119 149
f08aab 150         JPanel repositoriesPanel = new JPanel(new BorderLayout()) {
JM 151
152             private static final long serialVersionUID = 1L;
153
154             public Insets getInsets() {
155                 return _insets;
156             }
157         };
158         repositoriesPanel.add(repositoryPalette, BorderLayout.CENTER);
159
160         JPanel usersPanel = new JPanel(new BorderLayout()) {
161
162             private static final long serialVersionUID = 1L;
163
164             public Insets getInsets() {
165                 return _insets;
166             }
167         };
168         usersPanel.add(userPalette, BorderLayout.CENTER);
169
97d3af 170         preReceivePalette = new JPalette<String>(true);
f2dff4 171         preReceiveInherited = new JLabel();
97d3af 172         JPanel preReceivePanel = new JPanel(new BorderLayout(5, 5));
f2dff4 173         preReceivePanel.add(preReceivePalette, BorderLayout.CENTER);
JM 174         preReceivePanel.add(preReceiveInherited, BorderLayout.WEST);
175         
97d3af 176         postReceivePalette = new JPalette<String>(true);
f2dff4 177         postReceiveInherited = new JLabel();
97d3af 178         JPanel postReceivePanel = new JPanel(new BorderLayout(5, 5));
f2dff4 179         postReceivePanel.add(postReceivePalette, BorderLayout.CENTER);        
JM 180         postReceivePanel.add(postReceiveInherited, BorderLayout.WEST);
97d3af 181
f08aab 182         JTabbedPane panel = new JTabbedPane(JTabbedPane.TOP);
JM 183         panel.addTab(Translation.get("gb.general"), fieldsPanelTop);
184         panel.addTab(Translation.get("gb.teamMembers"), usersPanel);
185         panel.addTab(Translation.get("gb.restrictedRepositories"), repositoriesPanel);
97d3af 186         panel.addTab(Translation.get("gb.preReceiveScripts"), preReceivePanel);
JM 187         panel.addTab(Translation.get("gb.postReceiveScripts"), postReceivePanel);
f08aab 188
JM 189         JButton createButton = new JButton(Translation.get("gb.save"));
190         createButton.addActionListener(new ActionListener() {
191             public void actionPerformed(ActionEvent event) {
192                 if (validateFields()) {
193                     canceled = false;
194                     setVisible(false);
195                 }
196             }
197         });
198
199         JButton cancelButton = new JButton(Translation.get("gb.cancel"));
200         cancelButton.addActionListener(new ActionListener() {
201             public void actionPerformed(ActionEvent event) {
202                 canceled = true;
203                 setVisible(false);
204             }
205         });
206
207         JPanel controls = new JPanel();
208         controls.add(cancelButton);
209         controls.add(createButton);
0b9119 210
f08aab 211         JPanel centerPanel = new JPanel(new BorderLayout(5, 5)) {
JM 212
213             private static final long serialVersionUID = 1L;
214
215             @Override
216             public Insets getInsets() {
217                 return _insets;
218             }
219         };
220         centerPanel.add(panel, BorderLayout.CENTER);
221         centerPanel.add(controls, BorderLayout.SOUTH);
222
223         getContentPane().setLayout(new BorderLayout(5, 5));
224         getContentPane().add(centerPanel, BorderLayout.CENTER);
225         pack();
226     }
227
228     private JPanel newFieldPanel(String label, JComponent comp) {
229         JLabel fieldLabel = new JLabel(label);
230         fieldLabel.setFont(fieldLabel.getFont().deriveFont(Font.BOLD));
231         fieldLabel.setPreferredSize(new Dimension(150, 20));
232         JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0));
233         panel.add(fieldLabel);
234         panel.add(comp);
235         return panel;
236     }
237
238     private boolean validateFields() {
239         String tname = teamnameField.getText();
240         if (StringUtils.isEmpty(tname)) {
241             error("Please enter a team name!");
242             return false;
243         }
244
245         boolean rename = false;
246         // verify teamname uniqueness on create
247         if (isCreate) {
248             if (teamnames.contains(tname.toLowerCase())) {
249                 error(MessageFormat.format("Team name ''{0}'' is unavailable.", tname));
250                 return false;
251             }
252         } else {
253             // check rename collision
254             rename = !StringUtils.isEmpty(teamname) && !teamname.equalsIgnoreCase(tname);
255             if (rename) {
256                 if (teamnames.contains(tname.toLowerCase())) {
257                     error(MessageFormat.format(
258                             "Failed to rename ''{0}'' because ''{1}'' already exists.", teamname,
259                             tname));
260                     return false;
261                 }
262             }
263         }
264         team.name = tname;
265
476269 266         team.canAdmin = canAdminCheckbox.isSelected();
JM 267         team.canFork = canForkCheckbox.isSelected();
268         team.canCreate = canCreateCheckbox.isSelected();
269
0b9119 270         String ml = mailingListsField.getText();
JM 271         if (!StringUtils.isEmpty(ml)) {
272             Set<String> list = new HashSet<String>();
273             for (String address : ml.split("(,|\\s)")) {
274                 if (StringUtils.isEmpty(address)) {
275                     continue;
276                 }
277                 list.add(address.toLowerCase());
278             }
279             team.mailingLists.clear();
280             team.mailingLists.addAll(list);
281         }
282
822dfe 283         for (RegistrantAccessPermission rp : repositoryPalette.getPermissions()) {
JM 284             team.setRepositoryPermission(rp.registrant, rp.permission);
285         }
0b9119 286
f08aab 287         team.users.clear();
JM 288         team.users.addAll(userPalette.getSelections());
97d3af 289
JM 290         team.preReceiveScripts.clear();
291         team.preReceiveScripts.addAll(preReceivePalette.getSelections());
292
293         team.postReceiveScripts.clear();
294         team.postReceiveScripts.addAll(postReceivePalette.getSelections());
295
f08aab 296         return true;
JM 297     }
298
299     private void error(String message) {
300         JOptionPane.showMessageDialog(EditTeamDialog.this, message, Translation.get("gb.error"),
301                 JOptionPane.ERROR_MESSAGE);
302     }
303
304     public void setTeams(List<TeamModel> teams) {
305         teamnames.clear();
306         for (TeamModel team : teams) {
307             teamnames.add(team.name.toLowerCase());
308         }
309     }
310
822dfe 311     public void setRepositories(List<RepositoryModel> repositories, List<RegistrantAccessPermission> permissions) {
f08aab 312         List<String> restricted = new ArrayList<String>();
JM 313         for (RepositoryModel repo : repositories) {
314             if (repo.accessRestriction.exceeds(AccessRestrictionType.NONE)) {
315                 restricted.add(repo.name);
316             }
317         }
822dfe 318         
JM 319         // remove repositories for which team already has a permission
ba5424 320         if (permissions == null) {
JM 321             permissions = new ArrayList<RegistrantAccessPermission>();
322         } else {
323             for (RegistrantAccessPermission rp : permissions) {
324                 restricted.remove(rp.registrant);
325             }
f08aab 326         }
822dfe 327
JM 328         StringUtils.sortRepositorynames(restricted);
329         repositoryPalette.setObjects(restricted, permissions);
f08aab 330     }
0b9119 331
f08aab 332     public void setUsers(List<String> users, List<String> selected) {
JM 333         Collections.sort(users);
334         if (selected != null) {
335             Collections.sort(selected);
336         }
337         userPalette.setObjects(users, selected);
338     }
339
f2dff4 340     public void setPreReceiveScripts(List<String> unused, List<String> inherited,
JM 341             List<String> selected) {
97d3af 342         Collections.sort(unused);
JM 343         if (selected != null) {
344             Collections.sort(selected);
345         }
346         preReceivePalette.setObjects(unused, selected);
f2dff4 347         showInherited(inherited, preReceiveInherited);
97d3af 348     }
JM 349
f2dff4 350     public void setPostReceiveScripts(List<String> unused, List<String> inherited,
JM 351             List<String> selected) {
97d3af 352         Collections.sort(unused);
JM 353         if (selected != null) {
354             Collections.sort(selected);
355         }
356         postReceivePalette.setObjects(unused, selected);
f2dff4 357         showInherited(inherited, postReceiveInherited);
JM 358     }
359
360     private void showInherited(List<String> list, JLabel label) {
361         StringBuilder sb = new StringBuilder();
362         if (list != null && list.size() > 0) {
363             sb.append("<html><body><b>INHERITED</b><ul style=\"margin-left:5px;list-style-type: none;\">");
364             for (String script : list) {
365                 sb.append("<li>").append(script).append("</li>");
366             }
367             sb.append("</ul></body></html>");
368         }
369         label.setText(sb.toString());
97d3af 370     }
JM 371
f08aab 372     public TeamModel getTeam() {
JM 373         if (canceled) {
374             return null;
375         }
376         return team;
377     }
378 }