org.eclipse.ptp.ui.views.JobsListView.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.ptp.ui.views.JobsListView.java

Source

/*******************************************************************************
 * Copyright (c) 2008 IBM Corporation.
 * All rights reserved. This program and the accompanying materials
 * are 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:
 * IBM Corporation - Initial API and implementation
 *******************************************************************************/
package org.eclipse.ptp.ui.views;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.ptp.core.IModelManager;
import org.eclipse.ptp.core.PTPCorePlugin;
import org.eclipse.ptp.core.attributes.IAttribute;
import org.eclipse.ptp.core.attributes.IAttributeDefinition;
import org.eclipse.ptp.core.elements.IPJob;
import org.eclipse.ptp.core.elements.IPQueue;
import org.eclipse.ptp.core.elements.IPResourceManager;
import org.eclipse.ptp.core.elements.attributes.ElementAttributes;
import org.eclipse.ptp.core.elements.attributes.JobAttributes;
import org.eclipse.ptp.core.elements.events.IChangedMachineEvent;
import org.eclipse.ptp.core.elements.events.IChangedQueueEvent;
import org.eclipse.ptp.core.elements.events.INewJobEvent;
import org.eclipse.ptp.core.elements.events.INewMachineEvent;
import org.eclipse.ptp.core.elements.events.INewQueueEvent;
import org.eclipse.ptp.core.elements.events.IRemoveJobEvent;
import org.eclipse.ptp.core.elements.events.IRemoveMachineEvent;
import org.eclipse.ptp.core.elements.events.IRemoveQueueEvent;
import org.eclipse.ptp.core.elements.listeners.IResourceManagerChildListener;
import org.eclipse.ptp.core.events.IJobChangedEvent;
import org.eclipse.ptp.core.events.IResourceManagerAddedEvent;
import org.eclipse.ptp.core.events.IResourceManagerChangedEvent;
import org.eclipse.ptp.core.events.IResourceManagerErrorEvent;
import org.eclipse.ptp.core.events.IResourceManagerRemovedEvent;
import org.eclipse.ptp.core.listeners.IJobListener;
import org.eclipse.ptp.core.listeners.IResourceManagerListener;
import org.eclipse.ptp.internal.ui.actions.TerminateJobFromListAction;
import org.eclipse.ptp.ui.IPTPUIConstants;
import org.eclipse.ptp.ui.IRMSelectionListener;
import org.eclipse.ptp.ui.PTPUIPlugin;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.part.ViewPart;

public class JobsListView extends ViewPart {
    private final class JobListener implements IJobListener {

        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ptp.core.listeners.IJobListener#handleEvent(org.eclipse
         * .ptp.core.events.IJobChangeEvent)
         */
        public void handleEvent(IJobChangedEvent e) {
            IPResourceManager rm = (IPResourceManager) e.getSource().getAdapter(IPResourceManager.class);
            if (rm != null) {
                update(rm.getJobs());
            }

            // Refresh the terminate job button
            // TODO: scalability bottleneck
            PTPUIPlugin.getDisplay().syncExec(new Runnable() {
                public void run() {
                    terminateAllAction.updateTerminateJobState();
                }
            });

        }

    }

    private final class ResourceManagerListener implements IResourceManagerListener {
        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.ptp.core.listeners.IModelManagerListener#handleEvent
         * (org.eclipse.ptp.core.events.IResourceManagerAddedEvent)
         */
        public void handleEvent(IResourceManagerAddedEvent e) {
            /*
             * Add resource manager child listener so we get notified when new
             * machines are added to the model.
             */
            final IPResourceManager rm = (IPResourceManager) e.getResourceManager()
                    .getAdapter(IPResourceManager.class);
            rm.addChildListener(resourceManagerChildListener);
            rm.getResourceManager().addJobListener(jobListener);
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ptp.core.listeners.IResourceManagerListener#handleEvent
         * (org.eclipse.ptp.core.events.IResourceManagerChangedEvent)
         */
        public void handleEvent(IResourceManagerChangedEvent e) {
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ptp.core.listeners.IResourceManagerListener#handleEvent
         * (org.eclipse.ptp.core.events.IResourceManagerErrorEvent)
         */
        public void handleEvent(IResourceManagerErrorEvent e) {
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.ptp.core.listeners.IModelManagerListener#handleEvent
         * (org.eclipse.ptp.core.events.IResourceManagerRemovedEvent)
         */
        // Update the button here.
        public void handleEvent(IResourceManagerRemovedEvent e) {
            /*
             * Removed resource manager child listener when resource manager is
             * removed.
             */
            final IPResourceManager rm = (IPResourceManager) e.getResourceManager()
                    .getAdapter(IPResourceManager.class);
            rm.removeChildListener(resourceManagerChildListener);
            rm.getResourceManager().removeJobListener(jobListener);
        }
    }

    private final class RMChildListener implements IResourceManagerChildListener {
        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ptp.core.elements.listeners.IResourceManagerMachineListener
         * #handleEvent(org.eclipse.ptp.core.elements.events.
         * IResourceManagerChangedMachineEvent)
         */
        public void handleEvent(IChangedMachineEvent e) {
            // Don't need to do anything
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ptp.core.elements.listeners.IResourceManagerChildListener
         * #handleEvent(org.eclipse.ptp.core.elements.events.
         * IResourceManagerChangedQueueEvent)
         */
        public void handleEvent(IChangedQueueEvent e) {
            // Can safely ignore
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ptp.core.elements.listeners.IResourceManagerChildListener
         * #handleEvent(org.eclipse.ptp.core.elements.events.INewJobEvent)
         */
        public void handleEvent(final INewJobEvent e) {
            if (fColumnsNeedUpdating) {
                PTPUIPlugin.getDisplay().syncExec(new Runnable() {
                    public void run() {
                        addColumns(viewer, e.getJobs().iterator().next());
                    }
                });
            }
            refresh();
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ptp.core.elements.listeners.IResourceManagerMachineListener
         * #handleEvent(org.eclipse.ptp.core.elements.events.
         * IResourceManagerNewMachineEvent)
         */
        public void handleEvent(INewMachineEvent e) {
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ptp.core.elements.listeners.IResourceManagerChildListener
         * #handleEvent(org.eclipse.ptp.core.elements.events.INewQueueEvent)
         */
        public void handleEvent(INewQueueEvent e) {
            // Don't need to do anything
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ptp.core.elements.listeners.IResourceManagerChildListener
         * #handleEvent(org.eclipse.ptp.core.elements.events.IRemoveJobEvent)
         */
        public void handleEvent(IRemoveJobEvent e) {
            refresh();
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ptp.core.elements.listeners.IResourceManagerMachineListener
         * #handleEvent(org.eclipse.ptp.core.elements.events.
         * IResourceManagerRemoveMachineEvent)
         */
        public void handleEvent(IRemoveMachineEvent e) {
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ptp.core.elements.listeners.IResourceManagerChildListener
         * #handleEvent(org.eclipse.ptp.core.elements.events.
         * IResourceManagerRemoveQueueEvent)
         */
        public void handleEvent(IRemoveQueueEvent e) {
            // Don't need to do anything
        }
    }

    private TableViewer viewer;
    private TerminateJobFromListAction terminateAllAction;
    private IPResourceManager fSelectedRM = null;
    private IPQueue fSelectedQueue = null;
    private boolean fColumnsNeedUpdating = false;

    /*
     * Model listeners
     */
    private final IResourceManagerListener resourceManagerListener = new ResourceManagerListener();
    private final IResourceManagerChildListener resourceManagerChildListener = new RMChildListener();
    private final IJobListener jobListener = new JobListener();

    private final Set<IAttributeDefinition<?, ?, ?>> colDefs = Collections
            .synchronizedSet(new HashSet<IAttributeDefinition<?, ?, ?>>());

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets
     * .Composite)
     */
    @Override
    public void createPartControl(Composite parent) {
        parent.setLayout(new FillLayout());

        viewer = new TableViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);

        viewer.getTable().setLinesVisible(true);
        viewer.getTable().setHeaderVisible(true);
        viewer.setUseHashlookup(true);
        viewer.setContentProvider(new IStructuredContentProvider() {
            public void dispose() {
            }

            public Object[] getElements(Object inputElement) {
                /*
                 * Just get jobs from the queue if one is selected
                 */
                if (fSelectedQueue != null) {
                    return fSelectedQueue.getJobs();
                }
                /*
                 * Otherwise get jobs from all queues the RM knows about
                 */
                if (fSelectedRM != null) {
                    return getAllJobs(fSelectedRM).toArray(new IPJob[0]);
                }
                /*
                 * Otherwise get all jobs from all queues TODO: should probably
                 * not do this!
                 */
                Set<IPJob> jobs = new HashSet<IPJob>();
                for (IPResourceManager rm : PTPCorePlugin.getDefault().getModelManager().getUniverse()
                        .getResourceManagers()) {
                    jobs.addAll(getAllJobs(rm));
                }
                return jobs.toArray(new IPJob[0]);
            }

            public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            }
        });
        viewer.setSorter(new ViewerSorter() {
            @Override
            public int compare(Viewer viewer, Object j1, Object j2) {
                return ((IPJob) j1).getName().compareTo(((IPJob) j2).getName());
            }
        });

        createColumns(viewer);

        getSite().setSelectionProvider(viewer);

        MenuManager contextMenu = new MenuManager();
        contextMenu.setRemoveAllWhenShown(true);
        getSite().registerContextMenu(contextMenu, viewer);
        Control control = viewer.getControl();
        Menu menu = contextMenu.createContextMenu(control);
        control.setMenu(menu);

        // Use view toolbar
        IToolBarManager toolBarMgr = getViewSite().getActionBars().getToolBarManager();

        terminateAllAction = new TerminateJobFromListAction(this);
        toolBarMgr.add(new Separator(IPTPUIConstants.IUIACTIONGROUP));
        toolBarMgr.appendToGroup(IPTPUIConstants.IUIACTIONGROUP, terminateAllAction);

        /*
         * terminateAllAction = new TerminateJobAction(viewer);
         * toolBarMgr.appendToGroup(IPTPUIConstants.IUIACTIONGROUP,
         * terminateAllAction);
         */

        IModelManager mm = PTPCorePlugin.getDefault().getModelManager();
        viewer.setInput(mm.getUniverse());

        /*
         * Add us to any existing RM's. I guess it's possible we could miss a RM
         * if a new event arrives while we're doing this, but is it a problem?
         */
        for (IPResourceManager rm : mm.getUniverse().getResourceManagers()) {
            rm.addChildListener(resourceManagerChildListener);
            rm.getResourceManager().addJobListener(jobListener);
        }
        mm.addListener(resourceManagerListener);

        /*
         * Link this view to the ResourceManagerView
         */
        PTPUIPlugin.getDefault().getRMManager().addRMSelectionListener(new IRMSelectionListener() {
            public void selectionChanged(ISelection selection) {
                IPResourceManager oldRM = fSelectedRM;
                fSelectedQueue = null;
                if (selection.isEmpty()) {
                    fSelectedRM = null;
                } else {
                    TreePath path = ((ITreeSelection) selection).getPaths()[0];
                    Object segment = path.getFirstSegment();
                    if (segment instanceof IPResourceManager) {
                        fSelectedRM = (IPResourceManager) segment;
                        if (path.getLastSegment() instanceof IPQueue) {
                            fSelectedQueue = (IPQueue) path.getLastSegment();
                        }
                    }
                }
                if (oldRM != fSelectedRM) {
                    createColumns(viewer);
                }
                refresh();
            }

            public void setDefault(Object rm) {
                // Ignore
            }
        });
    }

    public TableViewer getViewer() {
        return viewer;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
     */
    @Override
    public void setFocus() {
    }

    /**
     * @param tableViewer
     * @param fontMetrics
     * @param attrDef
     */
    private void addColumn(final IAttributeDefinition<?, ?, ?> attrDef, boolean resizable) {
        TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);

        column.setLabelProvider(new ColumnLabelProvider() {

            /*
             * (non-Javadoc)
             * 
             * @see
             * org.eclipse.jface.viewers.ColumnLabelProvider#getImage(java.lang
             * .Object)
             */
            @Override
            public Image getImage(Object element) {
                /*
                 * If this is the state column, get the image, otherwise return
                 * null and just use the text.
                 */
                if (attrDef == JobAttributes.getStateAttributeDefinition()) {
                    IWorkbenchAdapter adapter = (IWorkbenchAdapter) Platform.getAdapterManager().getAdapter(element,
                            IWorkbenchAdapter.class);
                    if (adapter != null) {
                        return adapter.getImageDescriptor(element).createImage();
                    }
                }
                return null;
            }

            /*
             * (non-Javadoc)
             * 
             * @see
             * org.eclipse.jface.viewers.ColumnLabelProvider#getText(java.lang
             * .Object)
             */
            @Override
            public String getText(Object element) {
                /*
                 * If this is not the state column, then use the attribute text.
                 * If it is the state column, just return null an use the icon.
                 */
                IPJob job = (IPJob) element;
                if (attrDef != JobAttributes.getStateAttributeDefinition()) {
                    IAttribute<?, ?, ?> attr = job.getAttribute(attrDef.getId());
                    if (attr != null) {
                        return attr.getValueAsString();
                    }
                }
                return null;
            }

        });
        column.getColumn().setResizable(resizable);
        column.getColumn().setMoveable(true);
        // this will need to sort by the col
        // column.getColumn().addSelectionListener(getHeaderListener());
        String name = attrDef.getName();
        column.getColumn().setText(name);
        PixelConverter converter = new PixelConverter(viewer.getControl());
        int colWidth = converter.convertWidthInCharsToPixels(resizable ? name.length() + 5 : name.length());
        column.getColumn().setWidth(colWidth);
        colDefs.add(attrDef);
    }

    /**
     * @param tableViewer
     * @param job
     */
    private void addColumns(TableViewer tableViewer, IPJob job) {
        if (job != null) {
            for (IAttribute<?, ?, ?> attr : job.getAttributes()) {
                IAttributeDefinition<?, ?, ?> attrDef = attr.getDefinition();
                if (!colDefs.contains(attrDef) && attrDef.getDisplay()) {
                    addColumn(attrDef, true);
                }
            }
        }
    }

    /**
     * Create the columns for the table. This is done whenever the selection in
     * the RM view changes.
     * 
     * 1. Always create the state and name columns. 2. Assume that job
     * attributes from a single RM are always constant, so only look at the
     * first job from any queue. 3. Do this for each RM (if no RM selected)
     * 
     * @param tableViewer
     */
    private void createColumns(TableViewer tableViewer) {
        Table t = tableViewer.getTable();
        if (t.isDisposed()) {
            return;
        }
        for (TableColumn column : t.getColumns()) {
            column.dispose();
        }
        colDefs.clear();

        addColumn(JobAttributes.getStateAttributeDefinition(), false);
        addColumn(ElementAttributes.getNameAttributeDefinition(), true);

        IPJob[] jobs = getFirstJobs();

        if (jobs.length > 0) {
            for (IPJob job : jobs) {
                addColumns(tableViewer, job);
            }
            fColumnsNeedUpdating = false;
        } else {
            fColumnsNeedUpdating = true;
        }
    }

    /**
     * Find all jobs from all queues belonging to a RM
     * 
     * @param rm
     * @return set of jobs
     */
    private Set<IPJob> getAllJobs(IPResourceManager rm) {
        Set<IPJob> jobList = new HashSet<IPJob>();
        for (IPQueue queue : rm.getQueues()) {
            for (IPJob job : queue.getJobs()) {
                jobList.add(job);
            }
        }
        return jobList;
    }

    /**
     * Get the first job from the queue
     * 
     * @param queue
     * @return first job in the queue or null if there are no jobs
     */
    private IPJob getFirstJob(IPQueue queue) {
        IPJob[] jobs = queue.getJobs();
        if (jobs.length > 0) {
            return jobs[0];
        }
        return null;
    }

    /**
     * Finds the first few jobs to use to create the table columns If an RM
     * queue is selected, just return the first job If an RM is selected, return
     * the first job from one of the queues If no RM is selected, return the
     * first job from one of the queues in each RM
     * 
     * @return first job or null if there are no jobs
     */
    private IPJob[] getFirstJobs() {
        List<IPJob> jobsList = new ArrayList<IPJob>();

        if (fSelectedQueue != null) {
            IPJob job = getFirstJob(fSelectedQueue);
            if (job != null) {
                jobsList.add(job);
            }
        } else if (fSelectedRM != null) {
            for (IPQueue queue : fSelectedRM.getQueues()) {
                IPJob job = getFirstJob(queue);
                if (job != null) {
                    jobsList.add(job);
                    break;
                }
            }
        } else {
            for (IPResourceManager rm : PTPCorePlugin.getDefault().getModelManager().getUniverse()
                    .getResourceManagers()) {
                for (IPQueue queue : rm.getQueues()) {
                    IPJob job = getFirstJob(queue);
                    if (job != null) {
                        jobsList.add(job);
                        break;
                    }
                }
            }
        }
        return jobsList.toArray(new IPJob[0]);
    }

    /**
     * Refresh the viewer from the model.
     */
    private void refresh() {
        if (!viewer.getTable().isDisposed()) {
            PTPUIPlugin.getDisplay().asyncExec(new Runnable() {
                public void run() {
                    viewer.refresh();
                }
            });
        }
    }

    /**
     * Update the viewer if the supplied jobs have changed
     * 
     * @param jobs
     *            array of jobs that have changed
     */
    private void update(final IPJob[] jobs) {
        if (!viewer.getTable().isDisposed()) {
            PTPUIPlugin.getDisplay().asyncExec(new Runnable() {
                public void run() {
                    viewer.update(jobs, null);
                }
            });
        }
    }

}