/* | |
* Copyright 2011 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.client; | |
import java.awt.BorderLayout; | |
import java.awt.Dimension; | |
import java.awt.FlowLayout; | |
import java.awt.Font; | |
import java.awt.GridLayout; | |
import java.awt.Insets; | |
import java.awt.event.ActionEvent; | |
import java.awt.event.ActionListener; | |
import java.awt.event.KeyEvent; | |
import java.text.MessageFormat; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.HashSet; | |
import java.util.List; | |
import java.util.Set; | |
import javax.swing.ImageIcon; | |
import javax.swing.JButton; | |
import javax.swing.JCheckBox; | |
import javax.swing.JComponent; | |
import javax.swing.JDialog; | |
import javax.swing.JLabel; | |
import javax.swing.JOptionPane; | |
import javax.swing.JPanel; | |
import javax.swing.JRootPane; | |
import javax.swing.JTabbedPane; | |
import javax.swing.JTextField; | |
import javax.swing.KeyStroke; | |
import com.gitblit.Constants; | |
import com.gitblit.Constants.AccessRestrictionType; | |
import com.gitblit.Constants.AuthorizationControl; | |
import com.gitblit.Constants.RegistrantType; | |
import com.gitblit.Keys; | |
import com.gitblit.models.RegistrantAccessPermission; | |
import com.gitblit.models.RepositoryModel; | |
import com.gitblit.models.ServerSettings; | |
import com.gitblit.models.TeamModel; | |
import com.gitblit.utils.StringUtils; | |
public class EditTeamDialog extends JDialog { | |
private static final long serialVersionUID = 1L; | |
private final String teamname; | |
private final TeamModel team; | |
private final ServerSettings settings; | |
private boolean isCreate; | |
private boolean canceled = true; | |
private JTextField teamnameField; | |
private JCheckBox canAdminCheckbox; | |
private JCheckBox canForkCheckbox; | |
private JCheckBox canCreateCheckbox; | |
private JTextField mailingListsField; | |
private RegistrantPermissionsPanel repositoryPalette; | |
private JPalette<String> userPalette; | |
private JPalette<String> preReceivePalette; | |
private JLabel preReceiveInherited; | |
private JPalette<String> postReceivePalette; | |
private JLabel postReceiveInherited; | |
private Set<String> teamnames; | |
public EditTeamDialog(int protocolVersion, ServerSettings settings) { | |
this(protocolVersion, new TeamModel(""), settings); | |
this.isCreate = true; | |
setTitle(Translation.get("gb.newTeam")); | |
} | |
public EditTeamDialog(int protocolVersion, TeamModel aTeam, ServerSettings settings) { | |
super(); | |
this.teamname = aTeam.name; | |
this.team = new TeamModel(""); | |
this.settings = settings; | |
this.teamnames = new HashSet<String>(); | |
this.isCreate = false; | |
initialize(protocolVersion, aTeam); | |
setModal(true); | |
setTitle(Translation.get("gb.edit") + ": " + aTeam.name); | |
setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage()); | |
} | |
@Override | |
protected JRootPane createRootPane() { | |
KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); | |
JRootPane rootPane = new JRootPane(); | |
rootPane.registerKeyboardAction(new ActionListener() { | |
@Override | |
public void actionPerformed(ActionEvent actionEvent) { | |
setVisible(false); | |
} | |
}, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); | |
return rootPane; | |
} | |
private void initialize(int protocolVersion, TeamModel aTeam) { | |
teamnameField = new JTextField(aTeam.name == null ? "" : aTeam.name, 25); | |
canAdminCheckbox = new JCheckBox(Translation.get("gb.canAdminDescription"), aTeam.canAdmin); | |
canForkCheckbox = new JCheckBox(Translation.get("gb.canForkDescription"), aTeam.canFork); | |
canCreateCheckbox = new JCheckBox(Translation.get("gb.canCreateDescription"), aTeam.canCreate); | |
mailingListsField = new JTextField(aTeam.mailingLists == null ? "" | |
: StringUtils.flattenStrings(aTeam.mailingLists, " "), 50); | |
JPanel fieldsPanel = new JPanel(new GridLayout(0, 1)); | |
fieldsPanel.add(newFieldPanel(Translation.get("gb.teamName"), teamnameField)); | |
fieldsPanel.add(newFieldPanel(Translation.get("gb.canAdmin"), canAdminCheckbox)); | |
fieldsPanel.add(newFieldPanel(Translation.get("gb.canFork"), canForkCheckbox)); | |
fieldsPanel.add(newFieldPanel(Translation.get("gb.canCreate"), canCreateCheckbox)); | |
fieldsPanel.add(newFieldPanel(Translation.get("gb.mailingLists"), mailingListsField)); | |
final Insets _insets = new Insets(5, 5, 5, 5); | |
repositoryPalette = new RegistrantPermissionsPanel(RegistrantType.REPOSITORY); | |
userPalette = new JPalette<String>(); | |
JPanel fieldsPanelTop = new JPanel(new BorderLayout()); | |
fieldsPanelTop.add(fieldsPanel, BorderLayout.NORTH); | |
JPanel repositoriesPanel = new JPanel(new BorderLayout()) { | |
private static final long serialVersionUID = 1L; | |
@Override | |
public Insets getInsets() { | |
return _insets; | |
} | |
}; | |
repositoriesPanel.add(repositoryPalette, BorderLayout.CENTER); | |
JPanel usersPanel = new JPanel(new BorderLayout()) { | |
private static final long serialVersionUID = 1L; | |
@Override | |
public Insets getInsets() { | |
return _insets; | |
} | |
}; | |
usersPanel.add(userPalette, BorderLayout.CENTER); | |
preReceivePalette = new JPalette<String>(true); | |
preReceiveInherited = new JLabel(); | |
JPanel preReceivePanel = new JPanel(new BorderLayout(5, 5)); | |
preReceivePanel.add(preReceivePalette, BorderLayout.CENTER); | |
preReceivePanel.add(preReceiveInherited, BorderLayout.WEST); | |
postReceivePalette = new JPalette<String>(true); | |
postReceiveInherited = new JLabel(); | |
JPanel postReceivePanel = new JPanel(new BorderLayout(5, 5)); | |
postReceivePanel.add(postReceivePalette, BorderLayout.CENTER); | |
postReceivePanel.add(postReceiveInherited, BorderLayout.WEST); | |
JTabbedPane panel = new JTabbedPane(JTabbedPane.TOP); | |
panel.addTab(Translation.get("gb.general"), fieldsPanelTop); | |
panel.addTab(Translation.get("gb.teamMembers"), usersPanel); | |
panel.addTab(Translation.get("gb.restrictedRepositories"), repositoriesPanel); | |
panel.addTab(Translation.get("gb.preReceiveScripts"), preReceivePanel); | |
panel.addTab(Translation.get("gb.postReceiveScripts"), postReceivePanel); | |
JButton createButton = new JButton(Translation.get("gb.save")); | |
createButton.addActionListener(new ActionListener() { | |
@Override | |
public void actionPerformed(ActionEvent event) { | |
if (validateFields()) { | |
canceled = false; | |
setVisible(false); | |
} | |
} | |
}); | |
JButton cancelButton = new JButton(Translation.get("gb.cancel")); | |
cancelButton.addActionListener(new ActionListener() { | |
@Override | |
public void actionPerformed(ActionEvent event) { | |
canceled = true; | |
setVisible(false); | |
} | |
}); | |
JPanel controls = new JPanel(); | |
controls.add(cancelButton); | |
controls.add(createButton); | |
JPanel centerPanel = new JPanel(new BorderLayout(5, 5)) { | |
private static final long serialVersionUID = 1L; | |
@Override | |
public Insets getInsets() { | |
return _insets; | |
} | |
}; | |
centerPanel.add(panel, BorderLayout.CENTER); | |
centerPanel.add(controls, BorderLayout.SOUTH); | |
getContentPane().setLayout(new BorderLayout(5, 5)); | |
getContentPane().add(centerPanel, BorderLayout.CENTER); | |
pack(); | |
} | |
private JPanel newFieldPanel(String label, JComponent comp) { | |
JLabel fieldLabel = new JLabel(label); | |
fieldLabel.setFont(fieldLabel.getFont().deriveFont(Font.BOLD)); | |
fieldLabel.setPreferredSize(new Dimension(150, 20)); | |
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0)); | |
panel.add(fieldLabel); | |
panel.add(comp); | |
return panel; | |
} | |
private boolean validateFields() { | |
String tname = teamnameField.getText(); | |
if (StringUtils.isEmpty(tname)) { | |
error("Please enter a team name!"); | |
return false; | |
} | |
boolean rename = false; | |
// verify teamname uniqueness on create | |
if (isCreate) { | |
if (teamnames.contains(tname.toLowerCase())) { | |
error(MessageFormat.format("Team name ''{0}'' is unavailable.", tname)); | |
return false; | |
} | |
} else { | |
// check rename collision | |
rename = !StringUtils.isEmpty(teamname) && !teamname.equalsIgnoreCase(tname); | |
if (rename) { | |
if (teamnames.contains(tname.toLowerCase())) { | |
error(MessageFormat.format( | |
"Failed to rename ''{0}'' because ''{1}'' already exists.", teamname, | |
tname)); | |
return false; | |
} | |
} | |
} | |
team.name = tname; | |
team.canAdmin = canAdminCheckbox.isSelected(); | |
team.canFork = canForkCheckbox.isSelected(); | |
team.canCreate = canCreateCheckbox.isSelected(); | |
String ml = mailingListsField.getText(); | |
if (!StringUtils.isEmpty(ml)) { | |
Set<String> list = new HashSet<String>(); | |
for (String address : ml.split("(,|\\s)")) { | |
if (StringUtils.isEmpty(address)) { | |
continue; | |
} | |
list.add(address.toLowerCase()); | |
} | |
team.mailingLists.clear(); | |
team.mailingLists.addAll(list); | |
} | |
for (RegistrantAccessPermission rp : repositoryPalette.getPermissions()) { | |
team.setRepositoryPermission(rp.registrant, rp.permission); | |
} | |
team.users.clear(); | |
team.users.addAll(userPalette.getSelections()); | |
team.preReceiveScripts.clear(); | |
team.preReceiveScripts.addAll(preReceivePalette.getSelections()); | |
team.postReceiveScripts.clear(); | |
team.postReceiveScripts.addAll(postReceivePalette.getSelections()); | |
return true; | |
} | |
private void error(String message) { | |
JOptionPane.showMessageDialog(EditTeamDialog.this, message, Translation.get("gb.error"), | |
JOptionPane.ERROR_MESSAGE); | |
} | |
public void setTeams(List<TeamModel> teams) { | |
teamnames.clear(); | |
for (TeamModel team : teams) { | |
teamnames.add(team.name.toLowerCase()); | |
} | |
} | |
public void setRepositories(List<RepositoryModel> repositories, List<RegistrantAccessPermission> permissions) { | |
List<String> restricted = new ArrayList<String>(); | |
for (RepositoryModel repo : repositories) { | |
if (repo.accessRestriction.exceeds(AccessRestrictionType.NONE) | |
&& repo.authorizationControl.equals(AuthorizationControl.NAMED)) { | |
restricted.add(repo.name); | |
} | |
} | |
StringUtils.sortRepositorynames(restricted); | |
List<String> list = new ArrayList<String>(); | |
// repositories | |
list.add(".*"); | |
String prefix; | |
if (settings.hasKey(Keys.git.userRepositoryPrefix)) { | |
prefix = settings.get(Keys.git.userRepositoryPrefix).currentValue; | |
if (StringUtils.isEmpty(prefix)) { | |
prefix = Constants.DEFAULT_USER_REPOSITORY_PREFIX; | |
} | |
} else { | |
prefix = Constants.DEFAULT_USER_REPOSITORY_PREFIX; | |
} | |
if (prefix.length() == 1) { | |
// all repositories excluding personal repositories | |
list.add("[^" + prefix + "].*"); | |
} | |
String lastProject = null; | |
for (String repo : restricted) { | |
String projectPath = StringUtils.getFirstPathElement(repo); | |
if (lastProject == null || !lastProject.equalsIgnoreCase(projectPath)) { | |
lastProject = projectPath; | |
if (!StringUtils.isEmpty(projectPath)) { | |
// regex for all repositories within a project | |
list.add(projectPath + "/.*"); | |
} | |
list.add(repo); | |
} | |
} | |
// remove repositories for which user already has a permission | |
if (permissions == null) { | |
permissions = new ArrayList<RegistrantAccessPermission>(); | |
} else { | |
for (RegistrantAccessPermission rp : permissions) { | |
list.remove(rp.registrant); | |
} | |
} | |
repositoryPalette.setObjects(list, permissions); | |
} | |
public void setUsers(List<String> users, List<String> selected) { | |
Collections.sort(users); | |
if (selected != null) { | |
Collections.sort(selected); | |
} | |
userPalette.setObjects(users, selected); | |
} | |
public void setPreReceiveScripts(List<String> unused, List<String> inherited, | |
List<String> selected) { | |
Collections.sort(unused); | |
if (selected != null) { | |
Collections.sort(selected); | |
} | |
preReceivePalette.setObjects(unused, selected); | |
showInherited(inherited, preReceiveInherited); | |
} | |
public void setPostReceiveScripts(List<String> unused, List<String> inherited, | |
List<String> selected) { | |
Collections.sort(unused); | |
if (selected != null) { | |
Collections.sort(selected); | |
} | |
postReceivePalette.setObjects(unused, selected); | |
showInherited(inherited, postReceiveInherited); | |
} | |
private void showInherited(List<String> list, JLabel label) { | |
StringBuilder sb = new StringBuilder(); | |
if (list != null && list.size() > 0) { | |
sb.append("<html><body><b>INHERITED</b><ul style=\"margin-left:5px;list-style-type: none;\">"); | |
for (String script : list) { | |
sb.append("<li>").append(script).append("</li>"); | |
} | |
sb.append("</ul></body></html>"); | |
} | |
label.setText(sb.toString()); | |
} | |
public TeamModel getTeam() { | |
if (canceled) { | |
return null; | |
} | |
return team; | |
} | |
} |