James Moger
2011-10-28 3f5a936d62df428a713a04ff0436388c73e3c003
New login/edit registration dialog. Added url to status panel.
1 files added
6 files modified
429 ■■■■ changed files
src/com/gitblit/client/DateCellRenderer.java 12 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/EditRegistrationDialog.java 196 ●●●●● patch | view | raw | blame | history
src/com/gitblit/client/GitblitManager.java 127 ●●●●● patch | view | raw | blame | history
src/com/gitblit/client/GitblitPanel.java 2 ●●● patch | view | raw | blame | history
src/com/gitblit/client/GitblitRegistration.java 6 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/RegistrationsDialog.java 74 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/StatusPanel.java 12 ●●●●● patch | view | raw | blame | history
src/com/gitblit/client/DateCellRenderer.java
@@ -49,8 +49,16 @@
        super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        if (value instanceof Date) {
            Date date = (Date) value;
            String timeAgo = TimeUtils.timeAgo(date);
            String strDate = new SimpleDateFormat(pattern).format((Date) value);
            String timeAgo;
            String strDate;
            if (date.getTime() == 0) {
                timeAgo = "--";
                strDate = "never";
            } else {
                timeAgo = TimeUtils.timeAgo(date);
                strDate = new SimpleDateFormat(pattern).format((Date) value);
            }
            this.setText(timeAgo);
            this.setToolTipText(strDate);
        }
src/com/gitblit/client/EditRegistrationDialog.java
New file
@@ -0,0 +1,196 @@
/*
 * 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.Font;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
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.JRootPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import com.gitblit.utils.StringUtils;
/**
 * Dialog to create or edit a Gitblit registration.
 *
 * @author James Moger
 *
 */
public class EditRegistrationDialog extends JDialog {
    private static final long serialVersionUID = 1L;
    private JTextField urlField;
    private JTextField nameField;
    private JTextField accountField;
    private JPasswordField passwordField;
    private JCheckBox savePassword;
    private boolean canceled;
    private HeaderPanel headerPanel;
    public EditRegistrationDialog(Window owner) {
        this(owner, null, false);
    }
    public EditRegistrationDialog(Window owner, GitblitRegistration reg, boolean isLogin) {
        super(owner);
        initialize(reg, isLogin);
    }
    @Override
    protected JRootPane createRootPane() {
        KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
        JRootPane rootPane = new JRootPane();
        rootPane.registerKeyboardAction(new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                setVisible(false);
            }
        }, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
        return rootPane;
    }
    private void initialize(GitblitRegistration reg, boolean isLogin) {
        setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage());
        canceled = true;
        urlField = new JTextField(reg == null ? "" : reg.url, 30);
        nameField = new JTextField(reg == null ? "" : reg.name);
        accountField = new JTextField(reg == null ? "" : reg.account);
        passwordField = new JPasswordField(reg == null ? "" : new String(reg.password));
        savePassword = new JCheckBox("save password (passwords are NOT encrypted!)");
        savePassword.setSelected(reg == null ? false
                : (reg.password != null && reg.password.length > 0));
        JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5));
        panel.add(newLabelPanel(Translation.get("gb.name"), nameField));
        panel.add(newLabelPanel(Translation.get("gb.url"), urlField));
        panel.add(newLabelPanel(Translation.get("gb.username"), accountField));
        panel.add(newLabelPanel(Translation.get("gb.password"), passwordField));
        panel.add(newLabelPanel("", savePassword));
        JButton cancel = new JButton(Translation.get("gb.cancel"));
        cancel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                setVisible(false);
            }
        });
        final JButton save = new JButton(Translation.get(isLogin ? "gb.login" : "gb.save"));
        save.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (validateFields()) {
                    canceled = false;
                    setVisible(false);
                }
            }
        });
        // on enter in password field, save or login
        passwordField.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                save.doClick();
            }
        });
        JPanel controls = new JPanel();
        controls.add(cancel);
        controls.add(save);
        if (reg == null) {
            this.setTitle(Translation.get("gb.create"));
            headerPanel = new HeaderPanel(Translation.get("gb.create"), null);
        } else {
            this.setTitle(Translation.get(isLogin ? "gb.login" : "gb.edit"));
            headerPanel = new HeaderPanel(reg.name, null);
        }
        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(headerPanel, BorderLayout.NORTH);
        centerPanel.add(panel, BorderLayout.CENTER);
        centerPanel.add(controls, BorderLayout.SOUTH);
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(centerPanel, BorderLayout.CENTER);
        pack();
        setModal(true);
        if (isLogin) {
            passwordField.requestFocus();
        }
    }
    private JPanel newLabelPanel(String text, JComponent field) {
        JLabel label = new JLabel(text);
        label.setFont(label.getFont().deriveFont(Font.BOLD));
        label.setPreferredSize(new Dimension(75, 10));
        JPanel jpanel = new JPanel(new BorderLayout());
        jpanel.add(label, BorderLayout.WEST);
        jpanel.add(field, BorderLayout.CENTER);
        return jpanel;
    }
    private boolean validateFields() {
        String name = nameField.getText();
        if (StringUtils.isEmpty(name)) {
            error("Please enter a name for this registration!");
            return false;
        }
        String url = urlField.getText();
        if (StringUtils.isEmpty(url)) {
            error("Please enter a url for this registration!");
            return false;
        }
        return true;
    }
    private void error(String message) {
        JOptionPane.showMessageDialog(EditRegistrationDialog.this, message,
                Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
    }
    public GitblitRegistration getRegistration() {
        if (canceled) {
            return null;
        }
        GitblitRegistration reg = new GitblitRegistration(nameField.getText(), urlField.getText(),
                accountField.getText(), passwordField.getPassword());
        reg.savePassword = savePassword.isSelected();
        return reg;
    }
}
src/com/gitblit/client/GitblitManager.java
@@ -19,8 +19,6 @@
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -45,15 +43,12 @@
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
@@ -101,7 +96,7 @@
            public void windowClosing(WindowEvent event) {
                saveSizeAndPosition();
            }
            @Override
            public void windowOpened(WindowEvent event) {
                manageRegistrations();
@@ -177,25 +172,7 @@
        });
        serversMenu.add(manage);
        JMenuItem login = new JMenuItem(Translation.get("gb.login") + "...");
        login.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.CTRL_DOWN_MASK, false));
        login.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                loginPrompt(GitblitRegistration.LOCALHOST);
            }
        });
        serversMenu.add(login);
        return menuBar;
    }
    private JPanel newLabelPanel(String text, JTextField field) {
        JLabel label = new JLabel(text);
        label.setFont(label.getFont().deriveFont(Font.BOLD));
        label.setPreferredSize(new Dimension(75, 10));
        JPanel jpanel = new JPanel(new BorderLayout());
        jpanel.add(label, BorderLayout.WEST);
        jpanel.add(field, BorderLayout.CENTER);
        return jpanel;
    }
    private JPanel getCenterPanel() {
@@ -215,48 +192,23 @@
    }
    @Override
    public void loginPrompt(GitblitRegistration reg) {
        JTextField urlField = new JTextField(reg.url, 30);
        JTextField nameField = new JTextField(reg.name);
        JTextField accountField = new JTextField(reg.account);
        JPasswordField passwordField = new JPasswordField(new String(reg.password));
        JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5));
        panel.add(newLabelPanel(Translation.get("gb.name"), nameField));
        panel.add(newLabelPanel(Translation.get("gb.url"), urlField));
        panel.add(newLabelPanel(Translation.get("gb.username"), accountField));
        panel.add(newLabelPanel(Translation.get("gb.password"), passwordField));
        int result = JOptionPane.showConfirmDialog(GitblitManager.this, panel,
                Translation.get("gb.login"), JOptionPane.OK_CANCEL_OPTION);
        if (result != JOptionPane.OK_OPTION) {
            return;
        }
        String url = urlField.getText();
        if (StringUtils.isEmpty(url)) {
            return;
        }
        String originalName = reg.name;
        reg = new GitblitRegistration(nameField.getText(), url, accountField.getText(),
                passwordField.getPassword());
        if (!StringUtils.isEmpty(originalName) && !originalName.equals(reg.name)) {
            // delete old registration
            registrations.remove(originalName);
            try {
                StoredConfig config = getConfig();
                config.unsetSection("servers", originalName);
                config.save();
            } catch (Throwable t) {
                Utils.showException(GitblitManager.this, t);
    public void login(GitblitRegistration reg) {
        if (!reg.savePassword && (reg.password == null || reg.password.length == 0)) {
            // prompt for password
            EditRegistrationDialog dialog = new EditRegistrationDialog(this, reg, true);
            dialog.setLocationRelativeTo(GitblitManager.this);
            dialog.setVisible(true);
            reg = dialog.getRegistration();
            if (reg == null) {
                // user canceled
                return;
            }
        }
        login(reg);
    }
    @Override
    public void login(final GitblitRegistration reg) {
        // login
        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        final GitblitPanel panel = new GitblitPanel(reg);
        final GitblitRegistration registration = reg;
        final GitblitPanel panel = new GitblitPanel(registration);
        SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
            @Override
@@ -269,15 +221,19 @@
            protected void done() {
                try {
                    boolean success = get();
                    serverTabs.addTab(reg.name, panel);
                    serverTabs.addTab(registration.name, panel);
                    int idx = serverTabs.getTabCount() - 1;
                    serverTabs.setSelectedIndex(idx);
                    serverTabs.setTabComponentAt(idx, new ClosableTabComponent(reg.name, null,
                            serverTabs, panel));
                    reg.lastLogin = new Date();
                    saveRegistration(reg);
                    registrations.put(reg.name, reg);
                    serverTabs.setTabComponentAt(idx, new ClosableTabComponent(registration.name,
                            null, serverTabs, panel));
                    registration.lastLogin = new Date();
                    saveRegistration(registration.name, registration);
                    registrations.put(registration.name, registration);
                    rebuildRecentMenu();
                    if (!registration.savePassword) {
                        // clear password
                        registration.password = null;
                    }
                } catch (Throwable t) {
                    Throwable cause = t.getCause();
                    if (cause instanceof ConnectException) {
@@ -332,7 +288,11 @@
            StoredConfig config = getConfig();
            Set<String> servers = config.getSubsections("servers");
            for (String server : servers) {
                Date lastLogin = dateFormat.parse(config.getString("servers", server, "lastLogin"));
                Date lastLogin = new Date(0);
                String date = config.getString("servers", server, "lastLogin");
                if (!StringUtils.isEmpty(date)) {
                    lastLogin = dateFormat.parse(date);
                }
                String url = config.getString("servers", server, "url");
                String account = config.getString("servers", server, "account");
                char[] password;
@@ -340,7 +300,6 @@
                if (StringUtils.isEmpty(pw)) {
                    password = new char[0];
                } else {
                    // FIXME this is pretty lame
                    password = new String(Base64.decode(pw)).toCharArray();
                }
                GitblitRegistration reg = new GitblitRegistration(server, url, account, password);
@@ -352,21 +311,37 @@
        }
    }
    private void saveRegistration(GitblitRegistration reg) {
    @Override
    public boolean saveRegistration(String name, GitblitRegistration reg) {
        try {
            StoredConfig config = getConfig();
            if (!StringUtils.isEmpty(name) && !name.equals(reg.name)) {
                // delete old registration
                registrations.remove(name);
                config.unsetSection("servers", name);
            }
            // update registration
            config.setString("servers", reg.name, "url", reg.url);
            config.setString("servers", reg.name, "account", reg.account);
            // FIXME this is pretty lame
            config.setString("servers", reg.name, "password",
                    Base64.encodeBytes(new String(reg.password).getBytes("UTF-8")));
            config.setString("servers", reg.name, "lastLogin", dateFormat.format(reg.lastLogin));
            if (reg.savePassword) {
                config.setString("servers", reg.name, "password",
                        Base64.encodeBytes(new String(reg.password).getBytes("UTF-8")));
            } else {
                config.setString("servers", reg.name, "password", "");
            }
            if (reg.lastLogin != null) {
                config.setString("servers", reg.name, "lastLogin", dateFormat.format(reg.lastLogin));
            }
            config.save();
            return true;
        } catch (Throwable t) {
            Utils.showException(GitblitManager.this, t);
        }
        return false;
    }
    @Override
    public boolean deleteRegistrations(List<GitblitRegistration> list) {
        boolean success = false;
        try {
src/com/gitblit/client/GitblitPanel.java
@@ -564,7 +564,7 @@
    }
    private void updateStatusPanel() {
        statusPanel.setStatus(gitblit.getStatus());
        statusPanel.setStatus(gitblit.url, gitblit.getStatus());
    }
    private void filterRepositories(final String fragment) {
src/com/gitblit/client/GitblitRegistration.java
@@ -28,20 +28,20 @@
 */
public class GitblitRegistration implements Serializable, Comparable<GitblitRegistration> {
    public static final GitblitRegistration LOCALHOST = new GitblitRegistration("localhost",
            "https://localhost:8443", "admin", "admin".toCharArray());
    private static final long serialVersionUID = 1L;
    String name;
    String url;
    String account;
    char[] password;
    boolean savePassword;
    Date lastLogin;
    public GitblitRegistration(String name, String url, String account, char[] password) {
        this.url = url;
        this.account = account;
        this.password = password;
        this.savePassword = password != null && password.length > 0;
        if (StringUtils.isEmpty(name)) {
            this.name = url.substring(url.indexOf("//") + 2);
        } else {
@@ -51,6 +51,6 @@
    @Override
    public int compareTo(GitblitRegistration o) {
        return name.compareTo(o.name);
        return name.toLowerCase().compareTo(o.name.toLowerCase());
    }
}
src/com/gitblit/client/RegistrationsDialog.java
@@ -38,14 +38,22 @@
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
/**
 * Displays a list of registrations and allows management of server
 * registrations.
 *
 * @author James Moger
 *
 */
public class RegistrationsDialog extends JDialog {
    interface RegistrationListener {
        boolean deleteRegistrations(List<GitblitRegistration> list);
        void loginPrompt(GitblitRegistration reg);
        void login(GitblitRegistration reg);
        boolean saveRegistration(String name, GitblitRegistration reg);
        boolean deleteRegistrations(List<GitblitRegistration> list);
    }
    private static final long serialVersionUID = 1L;
@@ -87,12 +95,13 @@
        registrationsTable = Utils.newTable(model);
        registrationsTable.setRowHeight(nameRenderer.getFont().getSize() + 8);
        String id = registrationsTable.getColumnName(RegistrationsTableModel.Columns.Name.ordinal());
        String id = registrationsTable
                .getColumnName(RegistrationsTableModel.Columns.Name.ordinal());
        registrationsTable.getColumn(id).setCellRenderer(nameRenderer);
        registrationsTable.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    login(false);
                    login();
                }
            }
        });
@@ -100,8 +109,7 @@
        final JButton create = new JButton(Translation.get("gb.create"));
        create.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                RegistrationsDialog.this.setVisible(false);
                listener.loginPrompt(GitblitRegistration.LOCALHOST);
                create();
            }
        });
@@ -109,15 +117,15 @@
        login.setEnabled(false);
        login.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                login(false);
                login();
            }
        });
        final JButton loginPrompt = new JButton(Translation.get("gb.login") + "...");
        loginPrompt.setEnabled(false);
        loginPrompt.addActionListener(new ActionListener() {
        final JButton edit = new JButton(Translation.get("gb.edit"));
        edit.setEnabled(false);
        edit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                login(true);
                edit();
            }
        });
@@ -139,7 +147,7 @@
                        boolean singleSelection = registrationsTable.getSelectedRowCount() == 1;
                        boolean selected = registrationsTable.getSelectedRow() > -1;
                        login.setEnabled(singleSelection);
                        loginPrompt.setEnabled(singleSelection);
                        edit.setEnabled(singleSelection);
                        delete.setEnabled(selected);
                    }
                });
@@ -147,7 +155,7 @@
        JPanel controls = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
        controls.add(create);
        controls.add(login);
        controls.add(loginPrompt);
        controls.add(edit);
        controls.add(delete);
        final Insets insets = new Insets(5, 5, 5, 5);
@@ -159,6 +167,7 @@
                return insets;
            }
        };
        centerPanel.add(new HeaderPanel(Translation.get("gb.servers"), null), BorderLayout.NORTH);
        centerPanel.add(new JScrollPane(registrationsTable), BorderLayout.CENTER);
        centerPanel.add(controls, BorderLayout.SOUTH);
@@ -166,15 +175,42 @@
        getContentPane().add(centerPanel, BorderLayout.CENTER);
    }
    private void login(boolean prompt) {
    private void login() {
        int viewRow = registrationsTable.getSelectedRow();
        int modelRow = registrationsTable.convertRowIndexToModel(viewRow);
        GitblitRegistration reg = registrations.get(modelRow);
        RegistrationsDialog.this.setVisible(false);
        if (prompt) {
            listener.loginPrompt(reg);
        } else {
            listener.login(reg);
        listener.login(reg);
    }
    private void create() {
        EditRegistrationDialog dialog = new EditRegistrationDialog(getOwner());
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
        GitblitRegistration reg = dialog.getRegistration();
        if (reg == null) {
            return;
        }
        if (listener.saveRegistration(reg.name, reg)) {
            model.list.add(reg);
            model.fireTableDataChanged();
        }
    }
    private void edit() {
        int viewRow = registrationsTable.getSelectedRow();
        int modelRow = registrationsTable.convertRowIndexToModel(viewRow);
        GitblitRegistration reg = registrations.get(modelRow);
        String originalName = reg.name;
        EditRegistrationDialog dialog = new EditRegistrationDialog(getOwner(), reg, false);
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
        reg = dialog.getRegistration();
        if (reg == null) {
            return;
        }
        if (listener.saveRegistration(originalName, reg)) {
            model.fireTableDataChanged();
        }
    }
src/com/gitblit/client/StatusPanel.java
@@ -42,6 +42,7 @@
    private static final long serialVersionUID = 1L;
    private final Insets insets = new Insets(5, 5, 5, 5);
    private JLabel bootDate;
    private JLabel url;
    private JLabel servletContainer;
    private JLabel heapMaximum;
    private JLabel heapAllocated;
@@ -56,15 +57,16 @@
        initialize();
    }
    public StatusPanel(ServerStatus status) {
    public StatusPanel(String url, ServerStatus status) {
        this();
        setStatus(status);
        setStatus(url, status);
    }
    private void initialize() {
        version = new JLabel();
        releaseDate = new JLabel();
        bootDate = new JLabel();
        url = new JLabel();
        servletContainer = new JLabel();
        heapMaximum = new JLabel();
@@ -72,7 +74,7 @@
        heapUsed = new JLabel();
        JPanel fieldsPanel = new JPanel(new GridLayout(0, 1, 0, 5)) {
            private static final long serialVersionUID = 1L;
            @Override
@@ -83,6 +85,7 @@
        fieldsPanel.add(createFieldPanel("gb.version", version));
        fieldsPanel.add(createFieldPanel("gb.releaseDate", releaseDate));
        fieldsPanel.add(createFieldPanel("gb.bootDate", bootDate));
        fieldsPanel.add(createFieldPanel("gb.url", url));
        fieldsPanel.add(createFieldPanel("gb.servletContainer", servletContainer));
        fieldsPanel.add(createFieldPanel("gb.heapUsed", heapUsed));
        fieldsPanel.add(createFieldPanel("gb.heapAllocated", heapAllocated));
@@ -120,12 +123,13 @@
        return insets;
    }
    public void setStatus(ServerStatus status) {
    public void setStatus(String url, ServerStatus status) {
        headerPanel.setText(Translation.get("gb.status"));
        version.setText(Constants.NAME + (status.isGO ? " GO v" : " WAR v") + status.version);
        releaseDate.setText(status.releaseDate);
        bootDate.setText(status.bootDate.toString() + " (" + TimeUtils.timeAgo(status.bootDate)
                + ")");
        this.url.setText(url);
        servletContainer.setText(status.servletContainer);
        ByteFormat byteFormat = new ByteFormat();
        heapMaximum.setText(byteFormat.format(status.heapMaximum));