James Moger
2011-11-04 9119cf9d89257717b486c59b73bacc7c375501fc
Search added to gbapi. Search dialog for Manager. Misc Manager fixes.
1 files added
8 files modified
452 ■■■■■ changed files
build.xml 5 ●●●●● patch | view | raw | blame | history
src/com/gitblit/client/BranchRenderer.java 36 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/GitblitClient.java 23 ●●●●● patch | view | raw | blame | history
src/com/gitblit/client/MessageRenderer.java 19 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/RepositoriesPanel.java 34 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/SearchDialog.java 329 ●●●●● patch | view | raw | blame | history
src/com/gitblit/client/SubscriptionsDialog.java 2 ●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitBlitWebApp.properties 3 ●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/pages/BasePage.java 1 ●●●● patch | view | raw | blame | history
build.xml
@@ -454,6 +454,7 @@
            <resource file="${basedir}/resources/health_16x16.png" />
            <resource file="${basedir}/resources/feed_16x16.png" />
            <resource file="${basedir}/resources/bullet_feed.png" />
            <resource file="${basedir}/resources/search-icon.png" />
            <resource file="${basedir}/resources/blank.png" />
            <resource file="${basedir}/src/com/gitblit/wicket/GitBlitWebApp.properties" />
                
@@ -490,6 +491,7 @@
                <classpath refid="master-classpath" />
                <classfilter>
                    <exclude name="com.google.gson." />
                    <exclude name="com.sun.syndication." />
                </classfilter>
                <manifest>
                    <attribute name="Specification-Version" value="${gb.version}" />
@@ -506,6 +508,9 @@
                    <include name="gson*.jar" />
                    <exclude name="gson*-sources.jar" />
                    <exclude name="gson*-javadoc.jar" />
                    <include name="rome*.jar" />
                    <exclude name="rome*-sources.jar" />
                    <exclude name="rome*-javadoc.jar" />
                </fileset>
            </zip>
        </target>
src/com/gitblit/client/BranchRenderer.java
@@ -18,7 +18,9 @@
import java.awt.Color;
import java.awt.Component;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.ListCellRenderer;
import javax.swing.table.DefaultTableCellRenderer;
/**
@@ -28,7 +30,7 @@
 * @author James Moger
 * 
 */
public class BranchRenderer extends DefaultTableCellRenderer {
public class BranchRenderer extends DefaultTableCellRenderer implements ListCellRenderer {
    private static final long serialVersionUID = 1L;
@@ -39,7 +41,32 @@
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int column) {
        super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        String name = value.toString();
        if (value == null) {
            return this;
        }
        setText(value.toString());
        if (isSelected) {
            setForeground(table.getSelectionForeground());
        }
        return this;
    }
    @Override
    public Component getListCellRendererComponent(JList list, Object value, int index,
            boolean isSelected, boolean cellHasFocus) {
        setText(value.toString());
        if (isSelected) {
            setBackground(list.getSelectionBackground());
            setForeground(list.getSelectionForeground());
        } else {
            setBackground(list.getBackground());
        }
        return this;
    }
    @Override
    public void setText(String text) {
        String name = text;
        Color fg = getForeground();
        if (name.startsWith(R_HEADS)) {
            name = name.substring(R_HEADS.length());
@@ -48,8 +75,7 @@
            name = name.substring(R_REMOTES.length());
            fg = Color.decode("#6C6CBF");
        }
        setText(name);
        setForeground(isSelected ? table.getSelectionForeground() : fg);
        return this;
        setForeground(fg);
        super.setText(name);
    }
}
src/com/gitblit/client/GitblitClient.java
@@ -25,6 +25,7 @@
import java.util.Map;
import java.util.Set;
import com.gitblit.Constants;
import com.gitblit.GitBlitException.ForbiddenException;
import com.gitblit.GitBlitException.NotAllowedException;
import com.gitblit.GitBlitException.UnauthorizedException;
@@ -213,17 +214,31 @@
        return status;
    }
    public List<String> getBranches(String repository) {
        List<FeedModel> feeds = getAvailableFeeds(repository);
        List<String> branches = new ArrayList<String>();
        for (FeedModel feed : feeds) {
            branches.add(feed.branch);
        }
        Collections.sort(branches);
        return branches;
    }
    public List<FeedModel> getAvailableFeeds() {
        return availableFeeds;
    }
    public List<FeedModel> getAvailableFeeds(RepositoryModel repository) {
        return getAvailableFeeds(repository.name);
    }
    public List<FeedModel> getAvailableFeeds(String repository) {
        List<FeedModel> repositoryFeeds = new ArrayList<FeedModel>();
        if (repository == null) {
            return repositoryFeeds;
        }
        for (FeedModel feed : availableFeeds) {
            if (feed.repository.equalsIgnoreCase(repository.name)) {
            if (feed.repository.equalsIgnoreCase(repository)) {
                repositoryFeeds.add(feed);
            }
        }
@@ -292,6 +307,12 @@
        return syndicatedEntries;
    }
    public List<SyndicatedEntryModel> search(String repository, String branch, String fragment,
            Constants.SearchType type, int numberOfEntries) throws IOException {
        return SyndicationUtils.readSearchFeed(url, repository, branch, fragment, type,
                numberOfEntries, account, password);
    }
    public List<FederationModel> refreshFederationRegistrations() throws IOException {
        List<FederationModel> list = RpcUtils.getFederationRegistrations(url, account, password);
        federationRegistrations.clear();
src/com/gitblit/client/MessageRenderer.java
@@ -53,6 +53,10 @@
    private final JLabel branchLabel;
    public MessageRenderer() {
        this(null);
    }
    public MessageRenderer(GitblitClient gitblit) {
        super(new FlowLayout(FlowLayout.LEFT, 10, 1));
        this.gitblit = gitblit;
@@ -75,12 +79,17 @@
        messageLabel.setForeground(isSelected ? table.getSelectionForeground() : table
                .getForeground());
        SyndicatedEntryModel entry = (SyndicatedEntryModel) value;
        // show message in BOLD if its a new entry
        if (entry.published.after(gitblit.getLastFeedRefresh(entry.repository, entry.branch))) {
            messageLabel.setText("<html><body><b>" + entry.title);
        } else {
        if (gitblit == null) {
            // no gitblit client, just display message
            messageLabel.setText(entry.title);
        } else {
            // show message in BOLD if its a new entry
            if (entry.published.after(gitblit.getLastFeedRefresh(entry.repository, entry.branch))) {
                messageLabel.setText("<html><body><b>" + entry.title);
            } else {
                messageLabel.setText(entry.title);
            }
        }
        // reset ref label
src/com/gitblit/client/RepositoriesPanel.java
@@ -134,6 +134,15 @@
            }
        });
        final JButton searchRepository = new JButton(Translation.get("gb.search") + "...");
        searchRepository.setEnabled(false);
        searchRepository.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                RepositoryModel model = getSelectedRepositories().get(0);
                searchRepository(model);
            }
        });
        SubscribedRepositoryRenderer nameRenderer = new SubscribedRepositoryRenderer(gitblit);
        IndicatorsRenderer typeRenderer = new IndicatorsRenderer();
@@ -164,10 +173,18 @@
                    return;
                }
                boolean singleSelection = table.getSelectedRowCount() == 1;
                boolean selected = table.getSelectedRow() > -1;
                browseRepository.setEnabled(singleSelection);
                delRepository.setEnabled(selected);
                subscribeRepository.setEnabled(singleSelection);
                boolean selected = table.getSelectedRow() > -1;
                if (singleSelection) {
                    RepositoryModel repository = getSelectedRepositories().get(0);
                    browseRepository.setEnabled(repository.hasCommits);
                    searchRepository.setEnabled(repository.hasCommits);
                    subscribeRepository.setEnabled(repository.hasCommits);
                } else {
                    browseRepository.setEnabled(false);
                    searchRepository.setEnabled(false);
                    subscribeRepository.setEnabled(false);
                }
                delRepository.setEnabled(selected);
                if (selected) {
                    int viewRow = table.getSelectedRow();
                    int modelRow = table.convertRowIndexToModel(viewRow);
@@ -216,6 +233,7 @@
        repositoryControls.add(editRepository);
        repositoryControls.add(delRepository);
        repositoryControls.add(subscribeRepository);
        repositoryControls.add(searchRepository);
        setLayout(new BorderLayout(Utils.MARGIN, Utils.MARGIN));
        header = new HeaderPanel(Translation.get("gb.repositories"), "gitweb-favicon.png");
@@ -449,4 +467,12 @@
        }
    }
    protected void searchRepository(final RepositoryModel repository) {
        SearchDialog searchDialog = new SearchDialog(gitblit);
        if (repository != null) {
            searchDialog.selectRepository(repository);
        }
        searchDialog.setLocationRelativeTo(this);
        searchDialog.setVisible(true);
    }
}
src/com/gitblit/client/SearchDialog.java
New file
@@ -0,0 +1,329 @@
/*
 * 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.FlowLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import com.gitblit.Constants;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.SyndicatedEntryModel;
import com.gitblit.utils.StringUtils;
/**
 * The search dialog allows searching of a repository branch. This matches the
 * search implementation of the site.
 *
 * @author James Moger
 *
 */
public class SearchDialog extends JFrame {
    private static final long serialVersionUID = 1L;
    private final GitblitClient gitblit;
    private SyndicatedEntryTableModel tableModel;
    private HeaderPanel header;
    private JTable table;
    private JComboBox repositorySelector;
    private DefaultComboBoxModel branchChoices;
    private JComboBox branchSelector;
    private JComboBox searchTypeSelector;
    private JTextField searchFragment;
    private JComboBox maxHitsSelector;
    public SearchDialog(GitblitClient gitblit) {
        super();
        this.gitblit = gitblit;
        setTitle(Translation.get("gb.search"));
        setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage());
        initialize();
        setSize(900, 400);
    }
    private void initialize() {
        final JButton search = new JButton(Translation.get("gb.search"));
        search.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                search();
            }
        });
        final JButton viewCommit = new JButton(Translation.get("gb.view"));
        viewCommit.setEnabled(false);
        viewCommit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                viewCommit();
            }
        });
        final JButton viewCommitDiff = new JButton(Translation.get("gb.commitdiff"));
        viewCommitDiff.setEnabled(false);
        viewCommitDiff.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                viewCommitDiff();
            }
        });
        final JButton viewTree = new JButton(Translation.get("gb.tree"));
        viewTree.setEnabled(false);
        viewTree.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                viewTree();
            }
        });
        JPanel controls = new JPanel(new FlowLayout(FlowLayout.CENTER, Utils.MARGIN, 0));
        controls.add(viewCommit);
        controls.add(viewCommitDiff);
        controls.add(viewTree);
        NameRenderer nameRenderer = new NameRenderer();
        tableModel = new SyndicatedEntryTableModel();
        header = new HeaderPanel(Translation.get("gb.search"), "search-icon.png");
        table = Utils.newTable(tableModel, Utils.DATE_FORMAT);
        String name = table.getColumnName(SyndicatedEntryTableModel.Columns.Author.ordinal());
        table.setRowHeight(nameRenderer.getFont().getSize() + 8);
        table.getColumn(name).setCellRenderer(nameRenderer);
        name = table.getColumnName(SyndicatedEntryTableModel.Columns.Repository.ordinal());
        table.getColumn(name).setCellRenderer(nameRenderer);
        name = table.getColumnName(SyndicatedEntryTableModel.Columns.Branch.ordinal());
        table.getColumn(name).setCellRenderer(new BranchRenderer());
        name = table.getColumnName(SyndicatedEntryTableModel.Columns.Message.ordinal());
        table.getColumn(name).setCellRenderer(new MessageRenderer());
        table.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    if (e.isControlDown()) {
                        viewCommitDiff();
                    } else {
                        viewCommit();
                    }
                }
            }
        });
        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                if (e.getValueIsAdjusting()) {
                    return;
                }
                boolean singleSelection = table.getSelectedRowCount() == 1;
                viewCommit.setEnabled(singleSelection);
                viewCommitDiff.setEnabled(singleSelection);
                viewTree.setEnabled(singleSelection);
            }
        });
        repositorySelector = new JComboBox(gitblit.getRepositories().toArray());
        repositorySelector.setRenderer(nameRenderer);
        repositorySelector.setForeground(nameRenderer.getForeground());
        repositorySelector.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                // repopulate the branch list based on repository selection
                // preserve branch selection, if possible
                String selectedBranch = null;
                if (branchSelector.getSelectedIndex() > -1) {
                    selectedBranch = branchSelector.getSelectedItem().toString();
                }
                updateBranches();
                if (selectedBranch != null) {
                    if (branchChoices.getIndexOf(selectedBranch) > -1) {
                        branchChoices.setSelectedItem(selectedBranch);
                    }
                }
            }
        });
        branchChoices = new DefaultComboBoxModel();
        branchSelector = new JComboBox(branchChoices);
        branchSelector.setRenderer(new BranchRenderer());
        searchTypeSelector = new JComboBox(Constants.SearchType.values());
        searchTypeSelector.setSelectedItem(Constants.SearchType.COMMIT);
        maxHitsSelector = new JComboBox(new Integer[] { 25, 50, 75, 100 });
        maxHitsSelector.setSelectedIndex(-1);
        searchFragment = new JTextField(25);
        searchFragment.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                search();
            }
        });
        JPanel northControls = new JPanel(new FlowLayout(FlowLayout.LEFT, Utils.MARGIN, 0));
        northControls.add(new JLabel(Translation.get("gb.repository")));
        northControls.add(repositorySelector);
        northControls.add(new JLabel(Translation.get("gb.branch")));
        northControls.add(branchSelector);
        northControls.add(new JLabel(Translation.get("gb.type")));
        northControls.add(searchTypeSelector);
        northControls.add(new JLabel(Translation.get("gb.maxHits")));
        northControls.add(maxHitsSelector);
        northControls.add(searchFragment);
        northControls.add(search);
        JPanel northPanel = new JPanel(new BorderLayout(0, Utils.MARGIN));
        northPanel.add(header, BorderLayout.NORTH);
        northPanel.add(northControls, BorderLayout.CENTER);
        JPanel contentPanel = new JPanel() {
            private static final long serialVersionUID = 1L;
            @Override
            public Insets getInsets() {
                return Utils.INSETS;
            }
        };
        contentPanel.setLayout(new BorderLayout(Utils.MARGIN, Utils.MARGIN));
        contentPanel.add(northPanel, BorderLayout.NORTH);
        contentPanel.add(new JScrollPane(table), BorderLayout.CENTER);
        contentPanel.add(controls, BorderLayout.SOUTH);
        setLayout(new BorderLayout());
        add(contentPanel, BorderLayout.CENTER);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowOpened(WindowEvent event) {
                searchFragment.requestFocus();
            }
            @Override
            public void windowActivated(WindowEvent event) {
                searchFragment.requestFocus();
            }
        });
    }
    public void selectRepository(RepositoryModel repository) {
        repositorySelector.setSelectedItem(repository);
    }
    private void updateBranches() {
        String repository = null;
        if (repositorySelector.getSelectedIndex() > -1) {
            repository = repositorySelector.getSelectedItem().toString();
        }
        List<String> branches = gitblit.getBranches(repository);
        branchChoices.removeAllElements();
        for (String branch : branches) {
            branchChoices.addElement(branch);
        }
    }
    protected void search() {
        final String repository = repositorySelector.getSelectedItem().toString();
        final String branch = branchSelector.getSelectedIndex() > -1 ? branchSelector
                .getSelectedItem().toString() : null;
        final Constants.SearchType searchType = (Constants.SearchType) searchTypeSelector
                .getSelectedItem();
        final String fragment = searchFragment.getText();
        final int maxEntryCount = maxHitsSelector.getSelectedIndex() > -1 ? ((Integer) maxHitsSelector
                .getSelectedItem()) : -1;
        if (StringUtils.isEmpty(fragment)) {
            return;
        }
        SwingWorker<List<SyndicatedEntryModel>, Void> worker = new SwingWorker<List<SyndicatedEntryModel>, Void>() {
            @Override
            protected List<SyndicatedEntryModel> doInBackground() throws IOException {
                return gitblit.search(repository, branch, fragment, searchType, maxEntryCount);
            }
            @Override
            protected void done() {
                try {
                    List<SyndicatedEntryModel> results = get();
                    updateTable(true, fragment, results);
                } catch (Throwable t) {
                    Utils.showException(SearchDialog.this, t);
                }
            }
        };
        worker.execute();
    }
    protected void updateTable(boolean pack, String fragment, List<SyndicatedEntryModel> entries) {
        tableModel.entries.clear();
        tableModel.entries.addAll(entries);
        tableModel.fireTableDataChanged();
        setTitle(Translation.get("gb.search") + ": " + fragment + " (" + entries.size() + ")");
        header.setText(getTitle());
        if (pack) {
            Utils.packColumns(table, Utils.MARGIN);
        }
    }
    protected SyndicatedEntryModel getSelectedSyndicatedEntry() {
        int viewRow = table.getSelectedRow();
        int modelRow = table.convertRowIndexToModel(viewRow);
        SyndicatedEntryModel entry = tableModel.get(modelRow);
        return entry;
    }
    protected void viewCommit() {
        SyndicatedEntryModel entry = getSelectedSyndicatedEntry();
        Utils.browse(entry.link);
    }
    protected void viewCommitDiff() {
        SyndicatedEntryModel entry = getSelectedSyndicatedEntry();
        Utils.browse(entry.link.replace("/commit/", "/commitdiff/"));
    }
    protected void viewTree() {
        SyndicatedEntryModel entry = getSelectedSyndicatedEntry();
        Utils.browse(entry.link.replace("/commit/", "/tree/"));
    }
}
src/com/gitblit/client/SubscriptionsDialog.java
@@ -101,7 +101,7 @@
        feedsTable.getColumn(repository).setCellRenderer(nameRenderer);
        String branch = feedsTable.getColumnName(FeedsTableModel.Columns.Branch.ordinal());
        feedsTable.getColumn(branch).setCellRenderer(nameRenderer);
        feedsTable.getColumn(branch).setCellRenderer(new BranchRenderer());
        String subscribed = feedsTable.getColumnName(FeedsTableModel.Columns.Subscribed.ordinal());
        feedsTable.getColumn(subscribed).setCellRenderer(new BooleanCellRenderer());
src/com/gitblit/wicket/GitBlitWebApp.properties
@@ -179,4 +179,5 @@
gb.date = date
gb.activity = activity
gb.subscribe = subscribe
gb.branch = branch
gb.branch = branch
gb.maxHits = max hits
src/com/gitblit/wicket/pages/BasePage.java
@@ -84,6 +84,7 @@
            // Set Cookie
            WebResponse response = (WebResponse) getRequestCycle().getResponse();
            GitBlit.self().setCookie(response, user);
            continueToOriginalDestination();
        }
    }