Added new request type to retrieve Gitblit settings to implement the password preferences (minLength, storage type) and federation sets.tags/v0.7.0
<tr><td>LIST_FEDERATION_RESULTS</td><td>-</td><td><em>admin</em></td><td>-</td><td>List FederationModel</td></tr> | <tr><td>LIST_FEDERATION_RESULTS</td><td>-</td><td><em>admin</em></td><td>-</td><td>List FederationModel</td></tr> | ||||
<tr><td>LIST_FEDERATION_PROPOSALS</td><td>-</td><td><em>admin</em></td><td>-</td><td>List FederationProposal </td></tr> | <tr><td>LIST_FEDERATION_PROPOSALS</td><td>-</td><td><em>admin</em></td><td>-</td><td>List FederationProposal </td></tr> | ||||
<tr><td>LIST_FEDERATION_SETS</td><td>-</td><td><em>admin</em></td><td>-</td><td>List FederationSet </td></tr> | <tr><td>LIST_FEDERATION_SETS</td><td>-</td><td><em>admin</em></td><td>-</td><td>List FederationSet </td></tr> | ||||
<tr><td>LIST_SETTINGS</td><td>-</td><td><em>admin</em></td><td>-</td><td>Properties</td></tr> | |||||
</table> | </table> | ||||
### RPC Client | ### RPC Client |
LIST_REPOSITORIES, CREATE_REPOSITORY, EDIT_REPOSITORY, DELETE_REPOSITORY, | LIST_REPOSITORIES, CREATE_REPOSITORY, EDIT_REPOSITORY, DELETE_REPOSITORY, | ||||
LIST_USERS, CREATE_USER, EDIT_USER, DELETE_USER, LIST_REPOSITORY_MEMBERS, | LIST_USERS, CREATE_USER, EDIT_USER, DELETE_USER, LIST_REPOSITORY_MEMBERS, | ||||
SET_REPOSITORY_MEMBERS, LIST_FEDERATION_REGISTRATIONS, LIST_FEDERATION_RESULTS, | SET_REPOSITORY_MEMBERS, LIST_FEDERATION_REGISTRATIONS, LIST_FEDERATION_RESULTS, | ||||
LIST_FEDERATION_PROPOSALS, LIST_FEDERATION_SETS; | |||||
LIST_FEDERATION_PROPOSALS, LIST_FEDERATION_SETS, LIST_SETTINGS; | |||||
public static RpcRequest fromName(String name) { | public static RpcRequest fromName(String name) { | ||||
for (RpcRequest type : values()) { | for (RpcRequest type : values()) { |
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Properties; | |||||
import javax.servlet.ServletException; | import javax.servlet.ServletException; | ||||
import javax.servlet.http.HttpServletRequest; | import javax.servlet.http.HttpServletRequest; | ||||
} else { | } else { | ||||
response.sendError(HttpServletResponse.SC_FORBIDDEN); | response.sendError(HttpServletResponse.SC_FORBIDDEN); | ||||
} | } | ||||
} else if (RpcRequest.LIST_SETTINGS.equals(reqType)) { | |||||
// return the server's settings | |||||
Properties settings = new Properties(); | |||||
List<String> keys = GitBlit.getAllKeys(null); | |||||
for (String key:keys) { | |||||
String value = GitBlit.getString(key, null); | |||||
if (value != null) { | |||||
settings.put(key, value); | |||||
} | |||||
} | |||||
result = settings; | |||||
} | } | ||||
// send the result of the request | // send the result of the request |
/* | |||||
* 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.util.List; | |||||
import javax.swing.ImageIcon; | |||||
import javax.swing.JButton; | |||||
import javax.swing.JCheckBox; | |||||
import javax.swing.JComboBox; | |||||
import javax.swing.JComponent; | |||||
import javax.swing.JDialog; | |||||
import javax.swing.JLabel; | |||||
import javax.swing.JOptionPane; | |||||
import javax.swing.JPanel; | |||||
import javax.swing.JTextField; | |||||
import com.gitblit.Constants.AccessRestrictionType; | |||||
import com.gitblit.Constants.FederationStrategy; | |||||
import com.gitblit.models.RepositoryModel; | |||||
import com.gitblit.models.UserModel; | |||||
import com.gitblit.utils.StringUtils; | |||||
public class EditRepositoryDialog extends JDialog { | |||||
private static final long serialVersionUID = 1L; | |||||
private final RepositoryModel repository; | |||||
private boolean canceled = true; | |||||
private JTextField nameField; | |||||
private JTextField descriptionField; | |||||
private JCheckBox useTickets; | |||||
private JCheckBox useDocs; | |||||
private JCheckBox showRemoteBranches; | |||||
private JCheckBox showReadme; | |||||
private JCheckBox isFrozen; | |||||
private JComboBox accessRestriction; | |||||
private JComboBox federationStrategy; | |||||
private JComboBox owner; | |||||
private JPalette<String> usersPalette; | |||||
private JPalette<String> setsPalette; | |||||
public EditRepositoryDialog(List<UserModel> allusers) { | |||||
this(new RepositoryModel(), allusers); | |||||
setTitle("Create Repository"); | |||||
} | |||||
public EditRepositoryDialog(RepositoryModel aRepository, List<UserModel> allUsers) { | |||||
super(); | |||||
this.repository = new RepositoryModel(); | |||||
initialize(aRepository, allUsers); | |||||
setModal(true); | |||||
setTitle("Edit Repository: " + aRepository.name); | |||||
setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage()); | |||||
} | |||||
private void initialize(RepositoryModel anRepository, List<UserModel> allUsers) { | |||||
nameField = new JTextField(anRepository.name == null ? "" : anRepository.name, 35); | |||||
descriptionField = new JTextField(anRepository.description == null ? "" | |||||
: anRepository.description, 35); | |||||
owner = new JComboBox(allUsers.toArray()); | |||||
if (!StringUtils.isEmpty(anRepository.owner)) { | |||||
UserModel currentOwner = null; | |||||
for (UserModel user : allUsers) { | |||||
if (user.username.equalsIgnoreCase(anRepository.owner)) { | |||||
currentOwner = user; | |||||
break; | |||||
} | |||||
} | |||||
owner.setSelectedItem(currentOwner); | |||||
} | |||||
useTickets = new JCheckBox("distributed Ticgit issues", anRepository.useTickets); | |||||
useDocs = new JCheckBox("enumerates Markdown documentation in repository", | |||||
anRepository.useDocs); | |||||
showRemoteBranches = new JCheckBox("show remote branches", anRepository.showRemoteBranches); | |||||
showReadme = new JCheckBox("show a \"readme\" Markdown file on the summary page", | |||||
anRepository.showReadme); | |||||
isFrozen = new JCheckBox("deny push operations", anRepository.isFrozen); | |||||
accessRestriction = new JComboBox(AccessRestrictionType.values()); | |||||
accessRestriction.setSelectedItem(anRepository.accessRestriction); | |||||
federationStrategy = new JComboBox(FederationStrategy.values()); | |||||
federationStrategy.setSelectedItem(anRepository.federationStrategy); | |||||
JPanel fieldsPanel = new JPanel(new GridLayout(0, 1)); | |||||
fieldsPanel.add(newFieldPanel("name", nameField)); | |||||
fieldsPanel.add(newFieldPanel("description", descriptionField)); | |||||
fieldsPanel.add(newFieldPanel("owner", owner)); | |||||
fieldsPanel.add(newFieldPanel("enable tickets", useTickets)); | |||||
fieldsPanel.add(newFieldPanel("enable docs", useDocs)); | |||||
fieldsPanel.add(newFieldPanel("show remote branches", showRemoteBranches)); | |||||
fieldsPanel.add(newFieldPanel("show readme", showReadme)); | |||||
fieldsPanel.add(newFieldPanel("is frozen", isFrozen)); | |||||
usersPalette = new JPalette<String>(); | |||||
JPanel accessPanel = new JPanel(new BorderLayout(5, 5)); | |||||
accessPanel.add(newFieldPanel("access restriction", accessRestriction), BorderLayout.NORTH); | |||||
accessPanel.add(newFieldPanel("permitted users", usersPalette), BorderLayout.CENTER); | |||||
setsPalette = new JPalette<String>(); | |||||
JPanel federationPanel = new JPanel(new BorderLayout(5, 5)); | |||||
federationPanel.add(newFieldPanel("federation strategy", federationStrategy), | |||||
BorderLayout.NORTH); | |||||
federationPanel.add(newFieldPanel("federation sets", setsPalette), BorderLayout.CENTER); | |||||
JPanel panel = new JPanel(new BorderLayout(5, 5)); | |||||
panel.add(fieldsPanel, BorderLayout.NORTH); | |||||
panel.add(accessPanel, BorderLayout.CENTER); | |||||
panel.add(federationPanel, BorderLayout.SOUTH); | |||||
JButton createButton = new JButton("Save"); | |||||
createButton.addActionListener(new ActionListener() { | |||||
public void actionPerformed(ActionEvent event) { | |||||
if (validateFields()) { | |||||
canceled = false; | |||||
setVisible(false); | |||||
} | |||||
} | |||||
}); | |||||
JButton cancelButton = new JButton("Cancel"); | |||||
cancelButton.addActionListener(new ActionListener() { | |||||
public void actionPerformed(ActionEvent event) { | |||||
canceled = true; | |||||
setVisible(false); | |||||
} | |||||
}); | |||||
JPanel controls = new JPanel(); | |||||
controls.add(cancelButton); | |||||
controls.add(createButton); | |||||
final Insets _insets = new Insets(5, 5, 5, 5); | |||||
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(); | |||||
setLocationRelativeTo(null); | |||||
} | |||||
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() { | |||||
// TODO validate input and populate model | |||||
return true; | |||||
} | |||||
private void showValidationError(String message) { | |||||
JOptionPane.showMessageDialog(EditRepositoryDialog.this, message, "Validation Error", | |||||
JOptionPane.ERROR_MESSAGE); | |||||
} | |||||
public void setUsers(List<String> all, List<String> selected) { | |||||
usersPalette.setObjects(all, selected); | |||||
} | |||||
public void setFederationSets(List<String> all, List<String> selected) { | |||||
setsPalette.setObjects(all, selected); | |||||
} | |||||
public RepositoryModel getRepository() { | |||||
if (canceled) { | |||||
return null; | |||||
} | |||||
return repository; | |||||
} | |||||
} |
/* | |||||
* 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.text.MessageFormat; | |||||
import java.util.ArrayList; | |||||
import java.util.Arrays; | |||||
import java.util.List; | |||||
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.JPasswordField; | |||||
import javax.swing.JTextField; | |||||
import com.gitblit.Constants.AccessRestrictionType; | |||||
import com.gitblit.IStoredSettings; | |||||
import com.gitblit.Keys; | |||||
import com.gitblit.models.RepositoryModel; | |||||
import com.gitblit.models.UserModel; | |||||
import com.gitblit.utils.StringUtils; | |||||
public class EditUserDialog extends JDialog { | |||||
private static final long serialVersionUID = 1L; | |||||
private final UserModel user; | |||||
private final IStoredSettings settings; | |||||
private boolean canceled = true; | |||||
private JTextField usernameField; | |||||
private JPasswordField passwordField; | |||||
private JPasswordField confirmPasswordField; | |||||
private JCheckBox canAdminCheckbox; | |||||
private JCheckBox notFederatedCheckbox; | |||||
private JPalette<String> repositoryPalette; | |||||
public EditUserDialog(IStoredSettings settings) { | |||||
this(new UserModel(""), settings); | |||||
setTitle("Create User"); | |||||
} | |||||
public EditUserDialog(UserModel anUser, IStoredSettings settings) { | |||||
super(); | |||||
this.user = new UserModel(""); | |||||
this.settings = settings; | |||||
initialize(anUser); | |||||
setModal(true); | |||||
setTitle("Edit User: " + anUser.username); | |||||
setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage()); | |||||
} | |||||
private void initialize(UserModel anUser) { | |||||
usernameField = new JTextField(anUser.username == null ? "" : anUser.username, 25); | |||||
passwordField = new JPasswordField(anUser.password == null ? "" : anUser.password, 25); | |||||
confirmPasswordField = new JPasswordField(anUser.password == null ? "" : anUser.password, | |||||
25); | |||||
canAdminCheckbox = new JCheckBox("can administer Gitblit server", anUser.canAdmin); | |||||
notFederatedCheckbox = new JCheckBox( | |||||
"block federated Gitblit instances from pulling this account", | |||||
anUser.excludeFromFederation); | |||||
JPanel fieldsPanel = new JPanel(new GridLayout(0, 1)); | |||||
fieldsPanel.add(newFieldPanel("username", usernameField)); | |||||
fieldsPanel.add(newFieldPanel("password", passwordField)); | |||||
fieldsPanel.add(newFieldPanel("confirm password", confirmPasswordField)); | |||||
fieldsPanel.add(newFieldPanel("can admin", canAdminCheckbox)); | |||||
fieldsPanel.add(newFieldPanel("exclude from federation", notFederatedCheckbox)); | |||||
repositoryPalette = new JPalette<String>(); | |||||
JPanel panel = new JPanel(new BorderLayout()); | |||||
panel.add(fieldsPanel, BorderLayout.NORTH); | |||||
panel.add(newFieldPanel("restricted repositories", repositoryPalette), BorderLayout.CENTER); | |||||
JButton createButton = new JButton("Save"); | |||||
createButton.addActionListener(new ActionListener() { | |||||
public void actionPerformed(ActionEvent event) { | |||||
if (validateFields()) { | |||||
canceled = false; | |||||
setVisible(false); | |||||
} | |||||
} | |||||
}); | |||||
JButton cancelButton = new JButton("Cancel"); | |||||
cancelButton.addActionListener(new ActionListener() { | |||||
public void actionPerformed(ActionEvent event) { | |||||
canceled = true; | |||||
setVisible(false); | |||||
} | |||||
}); | |||||
JPanel controls = new JPanel(); | |||||
controls.add(cancelButton); | |||||
controls.add(createButton); | |||||
final Insets _insets = new Insets(5, 5, 5, 5); | |||||
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(); | |||||
setLocationRelativeTo(null); | |||||
} | |||||
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 uname = usernameField.getText(); | |||||
if (StringUtils.isEmpty(uname)) { | |||||
showValidationError("Please enter a username!"); | |||||
return false; | |||||
} | |||||
// TODO verify username uniqueness on create | |||||
// if (isCreate) { | |||||
// UserModel model = GitBlit.self().getUserModel(username); | |||||
// if (model != null) { | |||||
// error(MessageFormat.format("Username ''{0}'' is unavailable.", | |||||
// username)); | |||||
// return; | |||||
// } | |||||
// } | |||||
int minLength = settings.getInteger(Keys.realm.minPasswordLength, 5); | |||||
if (minLength < 4) { | |||||
minLength = 4; | |||||
} | |||||
char[] pw = passwordField.getPassword(); | |||||
if (pw == null || pw.length < minLength) { | |||||
showValidationError(MessageFormat.format( | |||||
"Password is too short. Minimum length is {0} characters.", minLength)); | |||||
return false; | |||||
} | |||||
char[] cpw = confirmPasswordField.getPassword(); | |||||
if (cpw == null || cpw.length != pw.length) { | |||||
showValidationError("Please confirm the password!"); | |||||
return false; | |||||
} | |||||
if (!Arrays.equals(pw, cpw)) { | |||||
showValidationError("Passwords do not match!"); | |||||
return false; | |||||
} | |||||
user.username = uname; | |||||
String type = settings.getString(Keys.realm.passwordStorage, "md5"); | |||||
if (type.equalsIgnoreCase("md5")) { | |||||
// store MD5 digest of password | |||||
user.password = StringUtils.MD5_TYPE + StringUtils.getMD5(new String(pw)); | |||||
} else { | |||||
user.password = new String(pw); | |||||
} | |||||
user.canAdmin = canAdminCheckbox.isSelected(); | |||||
user.excludeFromFederation = notFederatedCheckbox.isSelected(); | |||||
user.repositories.clear(); | |||||
user.repositories.addAll(repositoryPalette.getSelections()); | |||||
return true; | |||||
} | |||||
private void showValidationError(String message) { | |||||
JOptionPane.showMessageDialog(EditUserDialog.this, message, "Validation Error", | |||||
JOptionPane.ERROR_MESSAGE); | |||||
} | |||||
public void setRepositories(List<RepositoryModel> repositories, List<String> selected) { | |||||
List<String> restricted = new ArrayList<String>(); | |||||
for (RepositoryModel repo : repositories) { | |||||
if (repo.accessRestriction.exceeds(AccessRestrictionType.NONE)) { | |||||
restricted.add(repo.name); | |||||
} | |||||
} | |||||
StringUtils.sortRepositorynames(restricted); | |||||
if (selected != null) { | |||||
StringUtils.sortRepositorynames(selected); | |||||
} | |||||
repositoryPalette.setObjects(restricted, selected); | |||||
} | |||||
public UserModel getUser() { | |||||
if (canceled) { | |||||
return null; | |||||
} | |||||
return user; | |||||
} | |||||
} |
} | } | ||||
reg = new GitblitRegistration(nameField.getText(), url, accountField.getText(), | reg = new GitblitRegistration(nameField.getText(), url, accountField.getText(), | ||||
passwordField.getPassword()); | passwordField.getPassword()); | ||||
login(reg); | |||||
boolean success = login(reg); | |||||
registrations.add(0, reg); | registrations.add(0, reg); | ||||
rebuildRecentMenu(); | rebuildRecentMenu(); | ||||
return true; | |||||
return success; | |||||
} | } | ||||
private void login(GitblitRegistration reg) { | |||||
private boolean login(GitblitRegistration reg) { | |||||
try { | try { | ||||
GitblitPanel panel = new GitblitPanel(reg); | GitblitPanel panel = new GitblitPanel(reg); | ||||
panel.login(); | panel.login(); | ||||
serverTabs.setSelectedIndex(idx); | serverTabs.setSelectedIndex(idx); | ||||
serverTabs.setTabComponentAt(idx, new ClosableTabComponent(reg.name, null, serverTabs, | serverTabs.setTabComponentAt(idx, new ClosableTabComponent(reg.name, null, serverTabs, | ||||
panel)); | panel)); | ||||
return true; | |||||
} catch (IOException e) { | } catch (IOException e) { | ||||
JOptionPane.showMessageDialog(GitblitClient.this, e.getMessage(), "Error", | JOptionPane.showMessageDialog(GitblitClient.this, e.getMessage(), "Error", | ||||
JOptionPane.ERROR_MESSAGE); | JOptionPane.ERROR_MESSAGE); | ||||
} | } | ||||
return false; | |||||
} | } | ||||
private void rebuildRecentMenu() { | private void rebuildRecentMenu() { |
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.List; | import java.util.List; | ||||
import com.gitblit.Constants; | |||||
import com.gitblit.Launcher; | import com.gitblit.Launcher; | ||||
import com.gitblit.build.Build; | import com.gitblit.build.Build; | ||||
import com.gitblit.build.Build.DownloadListener; | import com.gitblit.build.Build.DownloadListener; | ||||
if (g != null) { | if (g != null) { | ||||
// Splash is 320x120 | // Splash is 320x120 | ||||
FontMetrics fm = g.getFontMetrics(); | FontMetrics fm = g.getFontMetrics(); | ||||
// paint startup status | |||||
g.setColor(Color.darkGray); | g.setColor(Color.darkGray); | ||||
int h = fm.getHeight() + fm.getMaxDescent(); | int h = fm.getHeight() + fm.getMaxDescent(); | ||||
int x = 5; | int x = 5; | ||||
g.setColor(Color.WHITE); | g.setColor(Color.WHITE); | ||||
int xw = fm.stringWidth(string); | int xw = fm.stringWidth(string); | ||||
g.drawString(string, x + ((w - xw) / 2), y - 5); | g.drawString(string, x + ((w - xw) / 2), y - 5); | ||||
// paint version | |||||
String ver = "v" + Constants.VERSION; | |||||
int vw = g.getFontMetrics().stringWidth(ver); | |||||
g.drawString(ver, 320 - vw - 5, 34); | |||||
g.dispose(); | g.dispose(); | ||||
splash.update(); | splash.update(); | ||||
} | } |
import java.awt.Component; | import java.awt.Component; | ||||
import java.awt.Desktop; | import java.awt.Desktop; | ||||
import java.awt.Dimension; | import java.awt.Dimension; | ||||
import java.awt.GridLayout; | |||||
import java.awt.Insets; | import java.awt.Insets; | ||||
import java.awt.event.ActionEvent; | import java.awt.event.ActionEvent; | ||||
import java.awt.event.ActionListener; | import java.awt.event.ActionListener; | ||||
import java.net.URI; | import java.net.URI; | ||||
import java.text.MessageFormat; | import java.text.MessageFormat; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Collections; | |||||
import java.util.Date; | import java.util.Date; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import javax.swing.JButton; | import javax.swing.JButton; | ||||
import javax.swing.JLabel; | import javax.swing.JLabel; | ||||
import javax.swing.JList; | import javax.swing.JList; | ||||
import javax.swing.JOptionPane; | |||||
import javax.swing.JPanel; | import javax.swing.JPanel; | ||||
import javax.swing.JScrollPane; | import javax.swing.JScrollPane; | ||||
import javax.swing.JTabbedPane; | import javax.swing.JTabbedPane; | ||||
import javax.swing.JTextField; | import javax.swing.JTextField; | ||||
import javax.swing.RowFilter; | import javax.swing.RowFilter; | ||||
import javax.swing.SwingConstants; | import javax.swing.SwingConstants; | ||||
import javax.swing.SwingWorker; | |||||
import javax.swing.event.ListSelectionEvent; | import javax.swing.event.ListSelectionEvent; | ||||
import javax.swing.event.ListSelectionListener; | import javax.swing.event.ListSelectionListener; | ||||
import javax.swing.table.DefaultTableCellRenderer; | import javax.swing.table.DefaultTableCellRenderer; | ||||
import javax.swing.table.TableColumn; | import javax.swing.table.TableColumn; | ||||
import javax.swing.table.TableRowSorter; | import javax.swing.table.TableRowSorter; | ||||
import com.gitblit.Constants.RpcRequest; | |||||
import com.gitblit.GitBlitException.ForbiddenException; | import com.gitblit.GitBlitException.ForbiddenException; | ||||
import com.gitblit.GitBlitException.UnauthorizedException; | |||||
import com.gitblit.IStoredSettings; | |||||
import com.gitblit.Keys; | |||||
import com.gitblit.client.ClosableTabComponent.CloseTabListener; | import com.gitblit.client.ClosableTabComponent.CloseTabListener; | ||||
import com.gitblit.models.FederationModel; | import com.gitblit.models.FederationModel; | ||||
import com.gitblit.models.RepositoryModel; | import com.gitblit.models.RepositoryModel; | ||||
private final Insets insets = new Insets(margin, margin, margin, margin); | private final Insets insets = new Insets(margin, margin, margin, margin); | ||||
private String url; | |||||
private final String url; | |||||
private String account; | |||||
private final String account; | |||||
private char[] password; | |||||
private final char[] password; | |||||
private boolean isAdmin; | |||||
private volatile boolean isAdmin; | |||||
private volatile List<UserModel> allUsers; | |||||
private volatile IStoredSettings settings; | |||||
private JTabbedPane tabs; | private JTabbedPane tabs; | ||||
private TableRowSorter<RepositoriesModel> defaultSorter; | private TableRowSorter<RepositoriesModel> defaultSorter; | ||||
private List<RepositoryModel> allRepositories; | |||||
public GitblitPanel(GitblitRegistration reg) { | public GitblitPanel(GitblitRegistration reg) { | ||||
this(reg.url, reg.account, reg.password); | this(reg.url, reg.account, reg.password); | ||||
} | } | ||||
} | } | ||||
}); | }); | ||||
JButton refreshRepositories = new JButton("Refresh"); | |||||
refreshRepositories.addActionListener(new ActionListener() { | |||||
public void actionPerformed(ActionEvent e) { | |||||
try { | |||||
refreshRepositoriesTable(); | |||||
} catch (ForbiddenException x) { | |||||
explainForbidden(RpcRequest.LIST_REPOSITORIES); | |||||
} catch (UnauthorizedException x) { | |||||
explainUnauthorized(RpcRequest.LIST_REPOSITORIES); | |||||
} catch (Throwable t) { | |||||
showException(t); | |||||
} | |||||
} | |||||
}); | |||||
createRepository = new JButton("Create"); | createRepository = new JButton("Create"); | ||||
createRepository.addActionListener(new ActionListener() { | createRepository.addActionListener(new ActionListener() { | ||||
public void actionPerformed(ActionEvent e) { | public void actionPerformed(ActionEvent e) { | ||||
System.out.println("TODO Create Repository"); | |||||
createRepository(); | |||||
} | } | ||||
}); | }); | ||||
editRepository.setEnabled(false); | editRepository.setEnabled(false); | ||||
editRepository.addActionListener(new ActionListener() { | editRepository.addActionListener(new ActionListener() { | ||||
public void actionPerformed(ActionEvent e) { | public void actionPerformed(ActionEvent e) { | ||||
for (RepositoryModel model : getSelectedRepositories()) { | |||||
System.out.println("TODO Edit " + model); | |||||
} | |||||
editRepository(getSelectedRepositories().get(0)); | |||||
} | } | ||||
}); | }); | ||||
delRepository.setEnabled(false); | delRepository.setEnabled(false); | ||||
delRepository.addActionListener(new ActionListener() { | delRepository.addActionListener(new ActionListener() { | ||||
public void actionPerformed(ActionEvent e) { | public void actionPerformed(ActionEvent e) { | ||||
for (RepositoryModel model : getSelectedRepositories()) { | |||||
System.out.println("TODO Delete " + model); | |||||
} | |||||
deleteRepositories(getSelectedRepositories()); | |||||
} | } | ||||
}); | }); | ||||
} | } | ||||
}); | }); | ||||
nameRenderer = new NameRenderer(Color.gray, new Color(0x00, 0x69, 0xD6)); | |||||
nameRenderer = new NameRenderer(); | |||||
typeRenderer = new TypeRenderer(); | typeRenderer = new TypeRenderer(); | ||||
sizeRenderer = new DefaultTableCellRenderer(); | sizeRenderer = new DefaultTableCellRenderer(); | ||||
repositoriesPanel.add(tablePanel, BorderLayout.CENTER); | repositoriesPanel.add(tablePanel, BorderLayout.CENTER); | ||||
repositoriesPanel.add(repositoryControls, BorderLayout.SOUTH); | repositoriesPanel.add(repositoryControls, BorderLayout.SOUTH); | ||||
JButton refreshUsers = new JButton("Refresh"); | |||||
refreshUsers.addActionListener(new ActionListener() { | |||||
public void actionPerformed(ActionEvent e) { | |||||
try { | |||||
refreshUsersTable(); | |||||
} catch (ForbiddenException x) { | |||||
explainForbidden(RpcRequest.LIST_USERS); | |||||
} catch (UnauthorizedException x) { | |||||
explainUnauthorized(RpcRequest.LIST_USERS); | |||||
} catch (Throwable t) { | |||||
showException(t); | |||||
} | |||||
} | |||||
}); | |||||
JButton createUser = new JButton("Create"); | JButton createUser = new JButton("Create"); | ||||
createUser.addActionListener(new ActionListener() { | createUser.addActionListener(new ActionListener() { | ||||
public void actionPerformed(ActionEvent e) { | public void actionPerformed(ActionEvent e) { | ||||
System.out.println("TODO Create User"); | |||||
createUser(); | |||||
} | } | ||||
}); | }); | ||||
editUser.setEnabled(false); | editUser.setEnabled(false); | ||||
editUser.addActionListener(new ActionListener() { | editUser.addActionListener(new ActionListener() { | ||||
public void actionPerformed(ActionEvent e) { | public void actionPerformed(ActionEvent e) { | ||||
for (UserModel user : getSelectedUsers()) { | |||||
System.out.println("TODO Edit " + user); | |||||
} | |||||
editUser(getSelectedUsers().get(0)); | |||||
} | } | ||||
}); | }); | ||||
delUser.setEnabled(false); | delUser.setEnabled(false); | ||||
delUser.addActionListener(new ActionListener() { | delUser.addActionListener(new ActionListener() { | ||||
public void actionPerformed(ActionEvent e) { | public void actionPerformed(ActionEvent e) { | ||||
for (UserModel user : getSelectedUsers()) { | |||||
System.out.println("TODO Delete " + user); | |||||
} | |||||
deleteUsers(getSelectedUsers()); | |||||
} | } | ||||
}); | }); | ||||
} | } | ||||
}); | }); | ||||
JPanel userControls = new JPanel(); | |||||
JPanel userControls = new JPanel(new GridLayout(0, 2)); | |||||
userControls.add(refreshUsers); | |||||
userControls.add(createUser); | userControls.add(createUser); | ||||
userControls.add(editUser); | userControls.add(editUser); | ||||
userControls.add(delUser); | userControls.add(delUser); | ||||
try { | try { | ||||
refreshUsersTable(); | refreshUsersTable(); | ||||
refreshSettings(); | |||||
isAdmin = true; | isAdmin = true; | ||||
refreshFederationPanel(); | refreshFederationPanel(); | ||||
} catch (ForbiddenException e) { | } catch (ForbiddenException e) { | ||||
private void refreshRepositoriesTable() throws IOException { | private void refreshRepositoriesTable() throws IOException { | ||||
Map<String, RepositoryModel> repositories = RpcUtils | Map<String, RepositoryModel> repositories = RpcUtils | ||||
.getRepositories(url, account, password); | .getRepositories(url, account, password); | ||||
allRepositories = new ArrayList<RepositoryModel>(repositories.values()); | |||||
Collections.sort(allRepositories); | |||||
repositoriesModel.list.clear(); | repositoriesModel.list.clear(); | ||||
repositoriesModel.list.addAll(repositories.values()); | |||||
repositoriesModel.list.addAll(allRepositories); | |||||
repositoriesModel.fireTableDataChanged(); | repositoriesModel.fireTableDataChanged(); | ||||
packColumns(repositoriesTable, 2); | packColumns(repositoriesTable, 2); | ||||
} | } | ||||
} | } | ||||
private void refreshUsersTable() throws IOException { | private void refreshUsersTable() throws IOException { | ||||
List<UserModel> users = RpcUtils.getUsers(url, account, password); | |||||
usersList.setListData(users.toArray()); | |||||
allUsers = RpcUtils.getUsers(url, account, password); | |||||
usersList.setListData(allUsers.toArray()); | |||||
} | |||||
private void refreshSettings() throws IOException { | |||||
settings = RpcUtils.getSettings(url, account, password); | |||||
} | } | ||||
private void refreshFederationPanel() throws IOException { | private void refreshFederationPanel() throws IOException { | ||||
@Override | @Override | ||||
public void closeTab(Component c) { | public void closeTab(Component c) { | ||||
} | } | ||||
/** | |||||
* Displays the create repository dialog and fires a SwingWorker to update | |||||
* the server, if appropriate. | |||||
* | |||||
*/ | |||||
protected void createRepository() { | |||||
EditRepositoryDialog dialog = new EditRepositoryDialog(allUsers); | |||||
dialog.setVisible(true); | |||||
final RepositoryModel newRepository = dialog.getRepository(); | |||||
if (newRepository == null) { | |||||
return; | |||||
} | |||||
final RpcRequest request = RpcRequest.CREATE_REPOSITORY; | |||||
SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() { | |||||
@Override | |||||
protected Boolean doInBackground() throws IOException { | |||||
return RpcUtils.createRepository(newRepository, url, account, password); | |||||
} | |||||
@Override | |||||
protected void done() { | |||||
try { | |||||
boolean success = get(); | |||||
if (success) { | |||||
refreshRepositoriesTable(); | |||||
} else { | |||||
String msg = MessageFormat.format( | |||||
"Failed to execute request \"{0}\" for repository \"{1}\".", | |||||
request.name(), newRepository.name); | |||||
JOptionPane.showMessageDialog(GitblitPanel.this, msg, "Error!", | |||||
JOptionPane.ERROR_MESSAGE); | |||||
} | |||||
} catch (ForbiddenException e) { | |||||
explainForbidden(request); | |||||
} catch (UnauthorizedException e) { | |||||
explainUnauthorized(request); | |||||
} catch (Throwable t) { | |||||
showException(t); | |||||
} | |||||
} | |||||
}; | |||||
worker.execute(); | |||||
} | |||||
/** | |||||
* Displays the edit repository dialog and fires a SwingWorker to update the | |||||
* server, if appropriate. | |||||
* | |||||
* @param repository | |||||
*/ | |||||
protected void editRepository(final RepositoryModel repository) { | |||||
EditRepositoryDialog dialog = new EditRepositoryDialog(repository, allUsers); | |||||
List<String> usernames = new ArrayList<String>(); | |||||
for (UserModel user : this.allUsers) { | |||||
usernames.add(user.username); | |||||
} | |||||
Collections.sort(usernames); | |||||
dialog.setUsers(usernames, null); | |||||
dialog.setFederationSets(settings.getStrings(Keys.federation.sets), | |||||
repository.federationSets); | |||||
dialog.setVisible(true); | |||||
final RepositoryModel revisedRepository = dialog.getRepository(); | |||||
if (revisedRepository == null) { | |||||
return; | |||||
} | |||||
final RpcRequest request = RpcRequest.EDIT_REPOSITORY; | |||||
SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() { | |||||
@Override | |||||
protected Boolean doInBackground() throws IOException { | |||||
return RpcUtils.updateRepository(repository.name, revisedRepository, url, account, | |||||
password); | |||||
} | |||||
@Override | |||||
protected void done() { | |||||
try { | |||||
boolean success = get(); | |||||
if (success) { | |||||
refreshRepositoriesTable(); | |||||
} else { | |||||
String msg = MessageFormat.format( | |||||
"Failed to execute request \"{0}\" for repository \"{1}\".", | |||||
request.name(), repository.name); | |||||
JOptionPane.showMessageDialog(GitblitPanel.this, msg, "Error!", | |||||
JOptionPane.ERROR_MESSAGE); | |||||
} | |||||
} catch (ForbiddenException e) { | |||||
explainForbidden(request); | |||||
} catch (UnauthorizedException e) { | |||||
explainUnauthorized(request); | |||||
} catch (Throwable t) { | |||||
showException(t); | |||||
} | |||||
} | |||||
}; | |||||
worker.execute(); | |||||
} | |||||
protected void deleteRepositories(final List<RepositoryModel> repositories) { | |||||
if (repositories == null || repositories.size() == 0) { | |||||
return; | |||||
} | |||||
StringBuilder message = new StringBuilder("Delete the following repositories?\n\n"); | |||||
for (RepositoryModel repository : repositories) { | |||||
message.append(repository.name).append("\n"); | |||||
} | |||||
int result = JOptionPane.showConfirmDialog(GitblitPanel.this, message.toString(), | |||||
"Delete Repositories?", JOptionPane.YES_NO_OPTION); | |||||
if (result == JOptionPane.YES_OPTION) { | |||||
final RpcRequest request = RpcRequest.DELETE_REPOSITORY; | |||||
SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() { | |||||
@Override | |||||
protected Boolean doInBackground() throws Exception { | |||||
boolean success = true; | |||||
for (RepositoryModel repository : repositories) { | |||||
success &= RpcUtils.deleteRepository(repository, url, account, password); | |||||
} | |||||
return success; | |||||
} | |||||
@Override | |||||
protected void done() { | |||||
try { | |||||
boolean success = get(); | |||||
if (success) { | |||||
refreshRepositoriesTable(); | |||||
} else { | |||||
String msg = "Failed to delete specified repositories!"; | |||||
JOptionPane.showMessageDialog(GitblitPanel.this, msg, "Error!", | |||||
JOptionPane.ERROR_MESSAGE); | |||||
} | |||||
} catch (ForbiddenException e) { | |||||
explainForbidden(request); | |||||
} catch (UnauthorizedException e) { | |||||
explainUnauthorized(request); | |||||
} catch (Throwable t) { | |||||
showException(t); | |||||
} | |||||
} | |||||
}; | |||||
worker.execute(); | |||||
} | |||||
} | |||||
/** | |||||
* Displays the create user dialog and fires a SwingWorker to update the | |||||
* server, if appropriate. | |||||
* | |||||
*/ | |||||
protected void createUser() { | |||||
EditUserDialog dialog = new EditUserDialog(settings); | |||||
dialog.setRepositories(allRepositories, null); | |||||
dialog.setVisible(true); | |||||
final UserModel newUser = dialog.getUser(); | |||||
if (newUser == null) { | |||||
return; | |||||
} | |||||
final RpcRequest request = RpcRequest.CREATE_USER; | |||||
SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() { | |||||
@Override | |||||
protected Boolean doInBackground() throws IOException { | |||||
return RpcUtils.createUser(newUser, url, account, password); | |||||
} | |||||
@Override | |||||
protected void done() { | |||||
try { | |||||
boolean success = get(); | |||||
if (success) { | |||||
refreshUsersTable(); | |||||
} else { | |||||
String msg = MessageFormat.format( | |||||
"Failed to execute request \"{0}\" for user \"{1}\".", | |||||
request.name(), newUser.username); | |||||
JOptionPane.showMessageDialog(GitblitPanel.this, msg, "Error!", | |||||
JOptionPane.ERROR_MESSAGE); | |||||
} | |||||
} catch (ForbiddenException e) { | |||||
explainForbidden(request); | |||||
} catch (UnauthorizedException e) { | |||||
explainUnauthorized(request); | |||||
} catch (Throwable t) { | |||||
showException(t); | |||||
} | |||||
} | |||||
}; | |||||
worker.execute(); | |||||
} | |||||
/** | |||||
* Displays the edit user dialog and fires a SwingWorker to update the | |||||
* server, if appropriate. | |||||
* | |||||
* @param user | |||||
*/ | |||||
protected void editUser(final UserModel user) { | |||||
EditUserDialog dialog = new EditUserDialog(user, settings); | |||||
dialog.setRepositories(allRepositories, new ArrayList<String>(user.repositories)); | |||||
dialog.setVisible(true); | |||||
final UserModel revisedUser = dialog.getUser(); | |||||
if (revisedUser == null) { | |||||
return; | |||||
} | |||||
final RpcRequest request = RpcRequest.EDIT_USER; | |||||
SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() { | |||||
@Override | |||||
protected Boolean doInBackground() throws IOException { | |||||
return RpcUtils.updateUser(user.username, revisedUser, url, account, password); | |||||
} | |||||
@Override | |||||
protected void done() { | |||||
try { | |||||
boolean success = get(); | |||||
if (success) { | |||||
refreshUsersTable(); | |||||
} else { | |||||
String msg = MessageFormat.format( | |||||
"Failed to execute request \"{0}\" for user \"{1}\".", | |||||
request.name(), user.username); | |||||
JOptionPane.showMessageDialog(GitblitPanel.this, msg, "Error!", | |||||
JOptionPane.ERROR_MESSAGE); | |||||
} | |||||
} catch (ForbiddenException e) { | |||||
explainForbidden(request); | |||||
} catch (UnauthorizedException e) { | |||||
explainUnauthorized(request); | |||||
} catch (Throwable t) { | |||||
showException(t); | |||||
} | |||||
} | |||||
}; | |||||
worker.execute(); | |||||
} | |||||
protected void deleteUsers(final List<UserModel> users) { | |||||
if (users == null || users.size() == 0) { | |||||
return; | |||||
} | |||||
StringBuilder message = new StringBuilder("Delete the following users?\n\n"); | |||||
for (UserModel user : users) { | |||||
message.append(user.username).append("\n"); | |||||
} | |||||
int result = JOptionPane.showConfirmDialog(GitblitPanel.this, message.toString(), | |||||
"Delete Users?", JOptionPane.YES_NO_OPTION); | |||||
if (result == JOptionPane.YES_OPTION) { | |||||
final RpcRequest request = RpcRequest.DELETE_USER; | |||||
SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() { | |||||
@Override | |||||
protected Boolean doInBackground() throws Exception { | |||||
boolean success = true; | |||||
for (UserModel user : users) { | |||||
success &= RpcUtils.deleteUser(user, url, account, password); | |||||
} | |||||
return success; | |||||
} | |||||
@Override | |||||
protected void done() { | |||||
try { | |||||
boolean success = get(); | |||||
if (success) { | |||||
refreshUsersTable(); | |||||
} else { | |||||
String msg = "Failed to delete specified users!"; | |||||
JOptionPane.showMessageDialog(GitblitPanel.this, msg, "Error!", | |||||
JOptionPane.ERROR_MESSAGE); | |||||
} | |||||
} catch (ForbiddenException e) { | |||||
explainForbidden(request); | |||||
} catch (UnauthorizedException e) { | |||||
explainUnauthorized(request); | |||||
} catch (Throwable t) { | |||||
showException(t); | |||||
} | |||||
} | |||||
}; | |||||
worker.execute(); | |||||
} | |||||
} | |||||
private void explainForbidden(RpcRequest request) { | |||||
String msg = MessageFormat.format( | |||||
"The request \"{0}\" has been forbidden by the Gitblit server @ {1}.", | |||||
request.name(), url); | |||||
JOptionPane.showMessageDialog(GitblitPanel.this, msg, "Forbidden", | |||||
JOptionPane.ERROR_MESSAGE); | |||||
} | |||||
private void explainUnauthorized(RpcRequest request) { | |||||
String msg = MessageFormat.format( | |||||
"The account \"{0}\" is not authorized to execute the request \"{1}\".", account, | |||||
request.name()); | |||||
JOptionPane.showMessageDialog(GitblitPanel.this, msg, "Unauthorized", | |||||
JOptionPane.ERROR_MESSAGE); | |||||
} | |||||
private void showException(Throwable t) { | |||||
// TODO show the unexpected exception | |||||
} | |||||
} | } |
/* | |||||
* 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.Color; | |||||
import java.awt.Dimension; | |||||
import java.awt.GridBagLayout; | |||||
import java.awt.GridLayout; | |||||
import java.awt.event.ActionEvent; | |||||
import java.awt.event.ActionListener; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import javax.swing.JButton; | |||||
import javax.swing.JLabel; | |||||
import javax.swing.JPanel; | |||||
import javax.swing.JScrollPane; | |||||
import javax.swing.JTable; | |||||
import javax.swing.table.AbstractTableModel; | |||||
public class JPalette<T> extends JPanel { | |||||
private static final long serialVersionUID = 1L; | |||||
private PaletteModel<T> availableModel; | |||||
private PaletteModel<T> selectedModel; | |||||
public JPalette() { | |||||
super(new BorderLayout(5, 5)); | |||||
availableModel = new PaletteModel<T>(); | |||||
selectedModel = new PaletteModel<T>(); | |||||
final JTable available = new JTable(availableModel); | |||||
final JTable selected = new JTable(selectedModel); | |||||
JButton add = new JButton("->"); | |||||
add.addActionListener(new ActionListener() { | |||||
public void actionPerformed(ActionEvent event) { | |||||
List<T> move = new ArrayList<T>(); | |||||
if (available.getSelectedRowCount() <= 0) { | |||||
return; | |||||
} | |||||
for (int row : available.getSelectedRows()) { | |||||
int modelIndex = available.convertRowIndexToModel(row); | |||||
T item = (T) availableModel.list.get(modelIndex); | |||||
move.add(item); | |||||
} | |||||
availableModel.list.removeAll(move); | |||||
selectedModel.list.addAll(move); | |||||
availableModel.fireTableDataChanged(); | |||||
selectedModel.fireTableDataChanged(); | |||||
} | |||||
}); | |||||
JButton subtract = new JButton("<-"); | |||||
subtract.addActionListener(new ActionListener() { | |||||
public void actionPerformed(ActionEvent event) { | |||||
List<T> move = new ArrayList<T>(); | |||||
if (selected.getSelectedRowCount() <= 0) { | |||||
return; | |||||
} | |||||
for (int row : selected.getSelectedRows()) { | |||||
int modelIndex = selected.convertRowIndexToModel(row); | |||||
T item = (T) selectedModel.list.get(modelIndex); | |||||
move.add(item); | |||||
} | |||||
selectedModel.list.removeAll(move); | |||||
availableModel.list.addAll(move); | |||||
selectedModel.fireTableDataChanged(); | |||||
availableModel.fireTableDataChanged(); | |||||
} | |||||
}); | |||||
JPanel controls = new JPanel(new GridLayout(0, 1, 0, 5)); | |||||
controls.add(add); | |||||
controls.add(subtract); | |||||
JPanel center = new JPanel(new GridBagLayout()); | |||||
center.add(controls); | |||||
add(newListPanel("Available", available), BorderLayout.WEST); | |||||
add(center, BorderLayout.CENTER); | |||||
add(newListPanel("Selected", selected), BorderLayout.EAST); | |||||
} | |||||
private JPanel newListPanel(String label, JTable table) { | |||||
NameRenderer nameRenderer = new NameRenderer(); | |||||
table.setCellSelectionEnabled(false); | |||||
table.setRowSelectionAllowed(true); | |||||
table.setRowHeight(nameRenderer.getFont().getSize() + 8); | |||||
table.getTableHeader().setReorderingAllowed(false); | |||||
table.setGridColor(new Color(0xd9d9d9)); | |||||
table.setBackground(Color.white); | |||||
table.getColumn(table.getColumnName(0)).setCellRenderer(nameRenderer); | |||||
JScrollPane jsp = new JScrollPane(table); | |||||
jsp.setPreferredSize(new Dimension(225, 175)); | |||||
JPanel panel = new JPanel(new BorderLayout()); | |||||
panel.add(new JLabel(label), BorderLayout.NORTH); | |||||
panel.add(jsp, BorderLayout.CENTER); | |||||
return panel; | |||||
} | |||||
public void setObjects(List<T> all, List<T> selected) { | |||||
List<T> available = new ArrayList<T>(all); | |||||
if (selected != null) { | |||||
available.removeAll(selected); | |||||
} | |||||
availableModel.list.clear(); | |||||
availableModel.list.addAll(available); | |||||
availableModel.fireTableDataChanged(); | |||||
if (selected != null) { | |||||
selectedModel.list.clear(); | |||||
selectedModel.list.addAll(selected); | |||||
selectedModel.fireTableDataChanged(); | |||||
} | |||||
} | |||||
public List<T> getSelections() { | |||||
return new ArrayList<T>(selectedModel.list); | |||||
} | |||||
public class PaletteModel<K> extends AbstractTableModel { | |||||
private static final long serialVersionUID = 1L; | |||||
List<K> list; | |||||
public PaletteModel() { | |||||
this(new ArrayList<K>()); | |||||
} | |||||
public PaletteModel(List<K> list) { | |||||
this.list = new ArrayList<K>(list); | |||||
} | |||||
@Override | |||||
public int getRowCount() { | |||||
return list.size(); | |||||
} | |||||
@Override | |||||
public int getColumnCount() { | |||||
return 1; | |||||
} | |||||
@Override | |||||
public String getColumnName(int column) { | |||||
return "Name"; | |||||
} | |||||
public Class<?> getColumnClass(int columnIndex) { | |||||
return String.class; | |||||
} | |||||
@Override | |||||
public Object getValueAt(int rowIndex, int columnIndex) { | |||||
K o = list.get(rowIndex); | |||||
return o.toString(); | |||||
} | |||||
} | |||||
} |
final String groupSpan; | final String groupSpan; | ||||
public NameRenderer() { | |||||
this(Color.gray, new Color(0x00, 0x69, 0xD6)); | |||||
} | |||||
public NameRenderer(Color group, Color repo) { | public NameRenderer(Color group, Color repo) { | ||||
groupSpan = "<span style='color:" + getHexColor(group) + "'>"; | groupSpan = "<span style='color:" + getHexColor(group) + "'>"; | ||||
setForeground(repo); | setForeground(repo); |
} | } | ||||
return gson().fromJson(json, type); | return gson().fromJson(json, type); | ||||
} | } | ||||
/** | |||||
* Reads a gson object from the specified url. | |||||
* | |||||
* @param url | |||||
* @param clazz | |||||
* @param username | |||||
* @param password | |||||
* @return the deserialized object | |||||
* @throws {@link IOException} | |||||
*/ | |||||
public static <X> X retrieveJson(String url, Class<X> clazz, String username, char[] password) | |||||
throws IOException { | |||||
String json = retrieveJsonString(url, username, password); | |||||
if (StringUtils.isEmpty(json)) { | |||||
return null; | |||||
} | |||||
return gson().fromJson(json, clazz); | |||||
} | |||||
/** | /** | ||||
* Retrieves a JSON message. | * Retrieves a JSON message. |
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Properties; | |||||
import com.gitblit.Constants; | import com.gitblit.Constants; | ||||
import com.gitblit.Constants.RpcRequest; | import com.gitblit.Constants.RpcRequest; | ||||
import com.gitblit.IStoredSettings; | |||||
import com.gitblit.models.FederationModel; | import com.gitblit.models.FederationModel; | ||||
import com.gitblit.models.FederationProposal; | import com.gitblit.models.FederationProposal; | ||||
import com.gitblit.models.FederationSet; | import com.gitblit.models.FederationSet; | ||||
List<FederationModel> list = new ArrayList<FederationModel>(registrations); | List<FederationModel> list = new ArrayList<FederationModel>(registrations); | ||||
return list; | return list; | ||||
} | } | ||||
/** | /** | ||||
* Retrieves the list of federation proposals. | * Retrieves the list of federation proposals. | ||||
* | * | ||||
* @return a collection of FederationProposal objects | * @return a collection of FederationProposal objects | ||||
* @throws IOException | * @throws IOException | ||||
*/ | */ | ||||
public static List<FederationProposal> getFederationProposals(String serverUrl, | |||||
String account, char[] password) throws IOException { | |||||
public static List<FederationProposal> getFederationProposals(String serverUrl, String account, | |||||
char[] password) throws IOException { | |||||
String url = asLink(serverUrl, RpcRequest.LIST_FEDERATION_PROPOSALS); | String url = asLink(serverUrl, RpcRequest.LIST_FEDERATION_PROPOSALS); | ||||
Collection<FederationProposal> proposals = JsonUtils.retrieveJson(url, PROPOSALS_TYPE, | Collection<FederationProposal> proposals = JsonUtils.retrieveJson(url, PROPOSALS_TYPE, | ||||
account, password); | account, password); | ||||
List<FederationProposal> list = new ArrayList<FederationProposal>(proposals); | List<FederationProposal> list = new ArrayList<FederationProposal>(proposals); | ||||
return list; | return list; | ||||
} | } | ||||
/** | /** | ||||
* Retrieves the list of federation repository sets. | * Retrieves the list of federation repository sets. | ||||
* | * | ||||
* @return a collection of FederationSet objects | * @return a collection of FederationSet objects | ||||
* @throws IOException | * @throws IOException | ||||
*/ | */ | ||||
public static List<FederationSet> getFederationSets(String serverUrl, | |||||
String account, char[] password) throws IOException { | |||||
public static List<FederationSet> getFederationSets(String serverUrl, String account, | |||||
char[] password) throws IOException { | |||||
String url = asLink(serverUrl, RpcRequest.LIST_FEDERATION_SETS); | String url = asLink(serverUrl, RpcRequest.LIST_FEDERATION_SETS); | ||||
Collection<FederationSet> sets = JsonUtils.retrieveJson(url, SETS_TYPE, | |||||
account, password); | |||||
Collection<FederationSet> sets = JsonUtils.retrieveJson(url, SETS_TYPE, account, password); | |||||
List<FederationSet> list = new ArrayList<FederationSet>(sets); | List<FederationSet> list = new ArrayList<FederationSet>(sets); | ||||
return list; | return list; | ||||
} | } | ||||
/** | |||||
* Retrieves the settings of the Gitblit server. | |||||
* | |||||
* @param serverUrl | |||||
* @param account | |||||
* @param password | |||||
* @return an IStoredSettings object | |||||
* @throws IOException | |||||
*/ | |||||
public static IStoredSettings getSettings(String serverUrl, String account, char[] password) | |||||
throws IOException { | |||||
String url = asLink(serverUrl, RpcRequest.LIST_SETTINGS); | |||||
Properties props = JsonUtils.retrieveJson(url, Properties.class, account, password); | |||||
RpcSettings settings = new RpcSettings(props); | |||||
return settings; | |||||
} | |||||
/** | /** | ||||
* Do the specified administrative action on the Gitblit server. | * Do the specified administrative action on the Gitblit server. | ||||
* | * | ||||
int resultCode = JsonUtils.sendJsonString(url, json, account, password); | int resultCode = JsonUtils.sendJsonString(url, json, account, password); | ||||
return resultCode == 200; | return resultCode == 200; | ||||
} | } | ||||
/** | |||||
* Settings implementation that wraps a retrieved properties instance. This | |||||
* class is used for RPC communication. | |||||
* | |||||
* @author James Moger | |||||
* | |||||
*/ | |||||
private static class RpcSettings extends IStoredSettings { | |||||
private final Properties properties = new Properties(); | |||||
public RpcSettings(Properties props) { | |||||
super(RpcSettings.class); | |||||
properties.putAll(props); | |||||
} | |||||
@Override | |||||
protected Properties read() { | |||||
return properties; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "RpcSettings"; | |||||
} | |||||
} | |||||
} | } |
gb.isFrozenDescription = deny push operations | gb.isFrozenDescription = deny push operations | ||||
gb.zip = zip | gb.zip = zip | ||||
gb.showReadme = show readme | gb.showReadme = show readme | ||||
gb.showReadmeDescription = show a \"readme\" markdown file on the summary page | |||||
gb.showReadmeDescription = show a \"readme\" Markdown file on the summary page | |||||
gb.nameDescription = use '/' to group repositories. e.g. libraries/mycoollib.git | gb.nameDescription = use '/' to group repositories. e.g. libraries/mycoollib.git | ||||
gb.ownerDescription = the owner may edit repository settings | gb.ownerDescription = the owner may edit repository settings | ||||
gb.blob = blob | gb.blob = blob | ||||
gb.federateThis = federate this repository | gb.federateThis = federate this repository | ||||
gb.federateOrigin = federate the origin | gb.federateOrigin = federate the origin | ||||
gb.excludeFromFederation = exclude from federation | gb.excludeFromFederation = exclude from federation | ||||
gb.excludeFromFederationDescription = block federated Gitblit instances from pulling this object | |||||
gb.excludeFromFederationDescription = block federated Gitblit instances from pulling this account | |||||
gb.tokens = federation tokens | gb.tokens = federation tokens | ||||
gb.tokenAllDescription = all repositories, users, & settings | gb.tokenAllDescription = all repositories, users, & settings | ||||
gb.tokenUnrDescription = all repositories & users | gb.tokenUnrDescription = all repositories & users |
import com.gitblit.Constants.AccessRestrictionType; | import com.gitblit.Constants.AccessRestrictionType; | ||||
import com.gitblit.GitBlitException.UnauthorizedException; | import com.gitblit.GitBlitException.UnauthorizedException; | ||||
import com.gitblit.IStoredSettings; | |||||
import com.gitblit.models.FederationModel; | import com.gitblit.models.FederationModel; | ||||
import com.gitblit.models.FederationProposal; | import com.gitblit.models.FederationProposal; | ||||
import com.gitblit.models.FederationSet; | import com.gitblit.models.FederationSet; | ||||
List<FederationSet> sets = RpcUtils.getFederationSets(url, account, password.toCharArray()); | List<FederationSet> sets = RpcUtils.getFederationSets(url, account, password.toCharArray()); | ||||
assertTrue("No federation sets were retrieved!", sets.size() > 0); | assertTrue("No federation sets were retrieved!", sets.size() > 0); | ||||
} | } | ||||
public void testSettings() throws Exception { | |||||
IStoredSettings settings = RpcUtils.getSettings(url, account, password.toCharArray()); | |||||
assertTrue("No settings were retrieved!", settings.getAllKeys(null).size() > 0); | |||||
} | |||||
} | } |