com.cloudbees.eclipse.dev.ui.views.build.BuildHistoryView.java Source code

Java tutorial

Introduction

Here is the source code for com.cloudbees.eclipse.dev.ui.views.build.BuildHistoryView.java

Source

/*******************************************************************************
 * Copyright (c) 2013 Cloud Bees, Inc.
 * All rights reserved. 
 * This program is made available under the terms of the 
 * Eclipse Public License v1.0 which accompanies this distribution, 
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Cloud Bees, Inc. - initial API and implementation 
 *******************************************************************************/
package com.cloudbees.eclipse.dev.ui.views.build;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

import com.cloudbees.eclipse.core.CBRemoteChangeAdapter;
import com.cloudbees.eclipse.core.CBRemoteChangeListener;
import com.cloudbees.eclipse.core.CloudBeesException;
import com.cloudbees.eclipse.core.jenkins.api.JenkinsBuild;
import com.cloudbees.eclipse.core.jenkins.api.JenkinsJobAndBuildsResponse;
import com.cloudbees.eclipse.core.util.Utils;
import com.cloudbees.eclipse.dev.ui.CBDEVImages;
import com.cloudbees.eclipse.dev.ui.CloudBeesDevUiPlugin;
import com.cloudbees.eclipse.dev.ui.actions.InvokeBuildAction;
import com.cloudbees.eclipse.dev.ui.actions.OpenBuildAction;
import com.cloudbees.eclipse.dev.ui.actions.OpenLogAction;
import com.cloudbees.eclipse.dev.ui.actions.ReloadBuildHistoryAction;
import com.cloudbees.eclipse.ui.CloudBeesUIPlugin;
import com.cloudbees.eclipse.ui.PreferenceConstants;

public class BuildHistoryView extends ViewPart implements IPropertyChangeListener {

    public static final String ID = "com.cloudbees.eclipse.dev.ui.views.build.BuildHistoryView";

    private TableViewer table;

    protected OpenBuildAction actionOpenBuild;
    protected OpenLogAction actionOpenLog;
    protected ReloadBuildHistoryAction actionReloadJobs;
    private InvokeBuildAction actionInvokeBuild;
    private Action actionOpenBuildInBrowser;

    private final Map<String, Image> stateIcons = new HashMap<String, Image>();

    private CBRemoteChangeListener jenkinsChangeListener;

    private BuildHistoryContentProvider contentProvider;

    private String jobUrl;

    protected Object selectedBuild;

    public BuildHistoryView() {
        super();
    }

    public Object getSelectedBuild() {
        return this.selectedBuild;
    }

    protected void setInput(final JenkinsJobAndBuildsResponse newView) {
        if (newView != null && newView.viewUrl != null) {
            IViewSite site = getViewSite();
            String secId = site.getSecondaryId();
            String servUrl = CloudBeesUIPlugin.getDefault().getJenkinsServiceForUrl(newView.viewUrl).getUrl();
            if (secId != null && servUrl != null && !secId.equals(Long.toString(servUrl.hashCode()))) {
                return; // another view
            }
        }

        if (newView == null || newView.builds == null) {
            setContentDescription("No builds available.");
            this.contentProvider.inputChanged(this.table, null, null);
        } else {
            String label = newView.name; // CloudBeesUIPlugin.getDefault().getJenkinsServiceForUrl(newView.viewUrl).getLabel();
            setContentDescription(label + " (" + new Date() + ")");
            setPartName("Build History [" + label + "]");
            this.contentProvider.inputChanged(this.table, null, newView);
        }

        if (newView != null) {
            this.jobUrl = newView.viewUrl;
        } else {
            this.jobUrl = null;
        }

        this.actionReloadJobs.setViewUrl(this.jobUrl);

        this.table.refresh();
    }

    @Override
    public void createPartControl(final Composite parent) {
        initImages();

        this.table = new TableViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION
        /*SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL*/);
        //Tree tree = viewer.getTree();
        //tree.setHeaderVisible(true);

        //table.getTable().setLinesVisible(true);
        this.table.getTable().setHeaderVisible(true);

        TableViewerColumn statusCol = createColumn("S", 22, BuildSorter.STATE, new CellLabelProvider() {
            @Override
            public void update(final ViewerCell cell) {
                JenkinsBuild build = (JenkinsBuild) cell.getViewerRow().getElement();

                String key = build.result;

                /*        ImageData[] imageDatas = new ImageLoader().load(new FileInputStream("myAnimated.gif"));
                        Image[] images = new Image[imageDatas.length];
                        for (int n = 0; n < imageDatas.length; n++) {
                          // images[n] = new Image(myTable.getDislay(), imageDatas[n]);
                        }
                 */
                //        if (job.color != null && job.color.contains("_")) {
                //          key = job.color.substring(0, job.color.indexOf("_"));
                //        }

                Image img = BuildHistoryView.this.stateIcons.get(key);

                if (img != null) {
                    cell.setText("");
                    cell.setImage(img);
                } else {
                    cell.setImage(null);
                    cell.setText(build.result);
                }

            }

        });
        statusCol.getColumn().setToolTipText("Status");

        //TODO i18n
        TableViewerColumn namecol = createColumn("Build", 50, BuildSorter.BUILD, new CellLabelProvider() {
            @Override
            public void update(final ViewerCell cell) {
                JenkinsBuild build = (JenkinsBuild) cell.getViewerRow().getElement();
                String val;
                try {
                    if (build.building) {
                        val = "building";
                    } else {
                        val = build.number.toString();
                    }
                } catch (Exception e) {
                    val = "";
                }
                cell.setText(val);
            }
        });

        createColumn("When", 100, BuildSorter.TIME, new CellLabelProvider() {
            @Override
            public void update(final ViewerCell cell) {
                JenkinsBuild build = (JenkinsBuild) cell.getViewerRow().getElement();

                if (build.timestamp != null) {
                    try {
                        cell.setText(
                                Utils.humanReadableTime(System.currentTimeMillis() - build.timestamp) + " ago");
                    } catch (Exception e) {
                        cell.setText("");
                    }
                } else {
                    cell.setText("");
                }
                cell.setImage(null);
            }
        });

        createColumn("Build Duration", 100, BuildSorter.DURATION, new CellLabelProvider() {
            @Override
            public void update(final ViewerCell cell) {
                JenkinsBuild build = (JenkinsBuild) cell.getViewerRow().getElement();
                if (build.duration != null) {
                    try {
                        cell.setText(Utils.humanReadableTime(build.duration));
                    } catch (Throwable t) {
                        cell.setText("");
                    }
                } else {
                    cell.setText("");
                }
            }
        });

        createColumn("Tests", 200, BuildSorter.TESTS, new CellLabelProvider() {
            @Override
            public void update(final ViewerCell cell) {
                JenkinsBuild build = (JenkinsBuild) cell.getViewerRow().getElement();
                try {
                    long total = 0;
                    long failed = 0;
                    long skipped = 0;
                    for (com.cloudbees.eclipse.core.jenkins.api.JenkinsBuild.Action action : build.actions) {
                        if ("testReport".equalsIgnoreCase(action.urlName)) {
                            total += action.totalCount;
                            failed += action.failCount;
                            skipped += action.skipCount;
                        }
                    }

                    if (total > 0 || failed > 0 || skipped > 0) {
                        String val = "Passed: " + (total - failed - skipped);
                        if (failed > 0) {
                            val += ", failed: " + failed;
                        }
                        if (skipped > 0) {
                            val += ", skipped: " + skipped;
                        }
                        cell.setText(val);
                    } else {
                        cell.setText("");
                    }
                } catch (Throwable t) {
                    cell.setText("");
                }
            }
        });
        createColumn("Cause", 250, BuildSorter.CAUSE, new CellLabelProvider() {
            @Override
            public void update(final ViewerCell cell) {
                JenkinsBuild build = (JenkinsBuild) cell.getViewerRow().getElement();
                String val = null;
                try {
                    for (com.cloudbees.eclipse.core.jenkins.api.JenkinsBuild.Action action : build.actions) {
                        if (action.causes != null && action.causes.length > 0) {
                            val = action.causes[0].shortDescription;
                            break;
                        }
                    }

                    if (val == null) {
                        val = "";
                    }
                    cell.setText(val);
                } catch (Throwable t) {
                    cell.setText("");
                }
            }
        });

        this.contentProvider = new BuildHistoryContentProvider();

        this.table.setContentProvider(this.contentProvider);

        BuildSorter sorter = new BuildSorter(BuildSorter.BUILD);
        sorter.setDirection(SWT.UP);
        this.table.setSorter(sorter);

        this.table.setInput(getViewSite());

        /*
            table.addFilter(new ViewerFilter() {
              @Override
              public boolean select(Viewer viewer, Object parentElement, Object element) {
        return true;
              }
            });*/

        this.table.addOpenListener(new IOpenListener() {

            public void open(final OpenEvent event) {
                ISelection sel = event.getSelection();

                if (sel instanceof IStructuredSelection) {
                    Object el = ((IStructuredSelection) sel).getFirstElement();
                    if (el instanceof JenkinsBuild) {
                        CloudBeesDevUiPlugin.getDefault().showBuild(((JenkinsBuild) el));
                    }
                }

            }

        });

        this.table.getTable().setSortColumn(namecol.getColumn());
        this.table.getTable().setSortDirection(SWT.DOWN);

        makeActions();
        contributeToActionBars();

        MenuManager popupMenu = new MenuManager();

        popupMenu.add(this.actionOpenBuild);
        popupMenu.add(this.actionOpenLog);
        popupMenu.add(new Separator("cloudActions"));
        popupMenu.add(this.actionOpenBuildInBrowser);
        popupMenu.add(this.actionInvokeBuild);
        popupMenu.add(new Separator("reloadActions"));
        popupMenu.add(this.actionReloadJobs);

        Menu menu = popupMenu.createContextMenu(this.table.getTable());
        this.table.getTable().setMenu(menu);

        this.table.addPostSelectionChangedListener(new ISelectionChangedListener() {

            public void selectionChanged(final SelectionChangedEvent event) {
                StructuredSelection sel = (StructuredSelection) event.getSelection();
                BuildHistoryView.this.selectedBuild = sel.getFirstElement();
                boolean enable = BuildHistoryView.this.selectedBuild != null;
                BuildHistoryView.this.actionInvokeBuild.setJob(BuildHistoryView.this.selectedBuild);
                BuildHistoryView.this.actionOpenBuildInBrowser.setEnabled(enable);
                BuildHistoryView.this.actionOpenBuild.setBuild(BuildHistoryView.this.selectedBuild);
                BuildHistoryView.this.actionOpenLog.setBuild(BuildHistoryView.this.selectedBuild);

                getViewSite().getActionBars().getToolBarManager().update(true);
            }
        });

        this.jenkinsChangeListener = new CBRemoteChangeAdapter() {

            public void activeJobHistoryChanged(final JenkinsJobAndBuildsResponse newView) {
                PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
                    public void run() {
                        BuildHistoryView.this.setInput(newView);
                    }
                });
            }

        };

        CloudBeesUIPlugin.getDefault().addCBRemoteChangeListener(this.jenkinsChangeListener);
    }

    private void initImages() {
        //TODO Refactor to use CBImages!
        this.stateIcons.put("", ImageDescriptor.createFromURL(
                CloudBeesDevUiPlugin.getDefault().getBundle().getResource("/icons/jenkins-icons/16x16/grey.gif"))
                .createImage());
        this.stateIcons.put("SUCCESS", ImageDescriptor.createFromURL(
                CloudBeesDevUiPlugin.getDefault().getBundle().getResource("/icons/jenkins-icons/16x16/blue.gif"))
                .createImage());
        this.stateIcons.put("FAILURE", ImageDescriptor.createFromURL(
                CloudBeesDevUiPlugin.getDefault().getBundle().getResource("/icons/jenkins-icons/16x16/red.gif"))
                .createImage());
        this.stateIcons.put("UNSTABLE", ImageDescriptor.createFromURL(
                CloudBeesDevUiPlugin.getDefault().getBundle().getResource("/icons/jenkins-icons/16x16/yellow.gif"))
                .createImage());

    }

    private TableViewerColumn createColumn(final String colName, final int width,
            final CellLabelProvider cellLabelProvider) {
        return createColumn(colName, width, -1, cellLabelProvider);
    }

    private TableViewerColumn createColumn(final String colName, final int width, final int sortCol,
            final CellLabelProvider cellLabelProvider) {
        final TableViewerColumn treeViewerColumn = new TableViewerColumn(this.table, SWT.NONE);
        TableColumn col = treeViewerColumn.getColumn();

        if (width > 0) {
            col.setWidth(width);
        }

        col.setText(colName);
        col.setMoveable(true);

        treeViewerColumn.setLabelProvider(cellLabelProvider);

        if (sortCol >= 0) {

            treeViewerColumn.getColumn().addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(final SelectionEvent e) {

                    int newOrder = SWT.DOWN;

                    if (BuildHistoryView.this.table.getTable().getSortColumn().equals(treeViewerColumn.getColumn())
                            && BuildHistoryView.this.table.getTable().getSortDirection() == SWT.DOWN) {
                        newOrder = SWT.UP;
                    }

                    BuildHistoryView.this.table.getTable().setSortColumn(treeViewerColumn.getColumn());
                    BuildHistoryView.this.table.getTable().setSortDirection(newOrder);
                    BuildSorter newSorter = new BuildSorter(sortCol);
                    newSorter.setDirection(newOrder);
                    BuildHistoryView.this.table.setSorter(newSorter);
                }
            });
        }
        return treeViewerColumn;
    }

    private void contributeToActionBars() {
        IActionBars bars = getViewSite().getActionBars();
        fillLocalPullDown(bars.getMenuManager());
        fillLocalToolBar(bars.getToolBarManager());
    }

    private void fillLocalToolBar(final IToolBarManager manager) {
        //    manager.add(this.actionOpenBuild);
        //    manager.add(this.actionOpenLog);
        manager.add(this.actionOpenBuildInBrowser);
        manager.add(this.actionInvokeBuild);
        manager.add(new Separator("reloadJob"));
        manager.add(this.actionReloadJobs);
    }

    private void fillLocalPullDown(final IMenuManager manager) {
        manager.add(this.actionOpenBuild);
        manager.add(this.actionOpenLog);
        //    manager.add(this.actionInvokeBuild);
        //    manager.add(new Separator());
        //    manager.add(this.actionReloadJobs);
    }

    private void makeActions() {

        CloudBeesUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);

        this.actionOpenBuild = new OpenBuildAction(false);
        this.actionOpenLog = new OpenLogAction();

        this.actionReloadJobs = new ReloadBuildHistoryAction(true);

        //    this.actionOpenLastBuildDetails = new OpenBuildAction(this);
        //    this.actionOpenLog = new OpenLogAction(this);
        //    this.actionDeleteJob = new DeleteJobAction(this);

        this.actionOpenBuildInBrowser = new Action("Open with Browser...", Action.AS_PUSH_BUTTON | SWT.NO_FOCUS) { //$NON-NLS-1$
            @Override
            public void run() {
                if (BuildHistoryView.this.selectedBuild != null) {
                    JenkinsBuild build = (JenkinsBuild) BuildHistoryView.this.selectedBuild;
                    CloudBeesUIPlugin.getDefault().openWithBrowser(build.url);
                }
            }
        };

        this.actionOpenBuildInBrowser.setToolTipText("Open with Browser"); //TODO i18n
        this.actionOpenBuildInBrowser
                .setImageDescriptor(CloudBeesDevUiPlugin.getImageDescription(CBDEVImages.IMG_BROWSER));
        this.actionOpenBuildInBrowser.setEnabled(false);

        this.actionInvokeBuild = new InvokeBuildAction();

        CloudBeesUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
    }

    @Override
    public void setFocus() {
        this.table.getControl().setFocus();
    }

    public void propertyChange(final PropertyChangeEvent event) {

        if (PreferenceConstants.P_JENKINS_INSTANCES.equals(event.getProperty())
                || PreferenceConstants.P_EMAIL.equals(event.getProperty())
                || PreferenceConstants.P_PASSWORD.equals(event.getProperty())) {
            try {
                CloudBeesDevUiPlugin.getDefault().showBuildHistory(this.jobUrl, false);
            } catch (CloudBeesException e) {
                //TODO i18n
                CloudBeesUIPlugin.showError("Failed to reload Jenkins jobs!", e);
            }
        }

        if (PreferenceConstants.P_JENKINS_REFRESH_INTERVAL.equals(event.getProperty())
                || PreferenceConstants.P_JENKINS_REFRESH_ENABLED.equals(event.getProperty())) {
            boolean enabled = CloudBeesUIPlugin.getDefault().getPreferenceStore()
                    .getBoolean(PreferenceConstants.P_JENKINS_REFRESH_ENABLED);
            int secs = CloudBeesUIPlugin.getDefault().getPreferenceStore()
                    .getInt(PreferenceConstants.P_JENKINS_REFRESH_INTERVAL);
            if (enabled && secs > 0) {
                //  startRefresher(); // start it if it was disabled by 0 value, do nothing if it was already running
            } else {
                //  stopRefresher();
            }
        }
    }

    @Override
    public void dispose() {
        CloudBeesUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
        CloudBeesUIPlugin.getDefault().removeCBRemoteChangeListener(this.jenkinsChangeListener);
        this.jenkinsChangeListener = null;
        //    stopRefresher();

        disposeImages();

        super.dispose();
    }

    private void disposeImages() {
        Iterator<Image> it = this.stateIcons.values().iterator();
        while (it.hasNext()) {
            Image img = it.next();
            img.dispose();
        }
        this.stateIcons.clear();
    }
}