| /* | |
| * 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; | |
| } | |
| } |