com.ifedorenko.p2browser.views.AbstractInstallableUnitHierarchyView.java Source code

Java tutorial

Introduction

Here is the source code for com.ifedorenko.p2browser.views.AbstractInstallableUnitHierarchyView.java

Source

/*******************************************************************************
 * Copyright (c) 2011 Igor Fedorenko
 * 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:
 *      Igor Fedorenko - initial API and implementation
 *******************************************************************************/

package com.ifedorenko.p2browser.views;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EventObject;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.query.IQueryable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.wb.swt.ResourceManager;

import com.ifedorenko.p2browser.director.IInstallableUnitHierarchyCalculator;
import com.ifedorenko.p2browser.director.InstallableUnitDAG;
import com.ifedorenko.p2browser.model.IGroupedInstallableUnits;
import com.ifedorenko.p2browser.model.InstallableUnitDependencyTree;
import com.ifedorenko.p2browser.model.match.IInstallableUnitMatcher;
import com.ifedorenko.p2browser.model.match.InstallableUnitsMatcher;
import com.ifedorenko.p2browser.views.InstallableUnitFilterComposite.IFilterChangeListener;

public abstract class AbstractInstallableUnitHierarchyView extends ViewPart {
    TreeViewer hierarchyTreeViewer;

    TableViewer listTableViewer;

    InstallableUnitDAG dag;

    IInstallableUnitMatcher unitMatcher;

    Font boldFont;

    boolean filterHierarchy = true;

    boolean filterList = false;

    boolean sortList = true;

    Action filterHierarchyAction;

    Job applyFilterJob = new Job("Apply filter") {
        @Override
        protected IStatus run(IProgressMonitor monitor) {
            getSite().getShell().getDisplay().asyncExec(new Runnable() {
                @Override
                public void run() {
                    applyHierachyFilter();
                    applyListFilter();
                }
            });
            return Status.OK_STATUS;
        }
    };

    // TODO share decoration logic with MetadataRepositoryView
    private class LabelProvider extends InstallableUnitLabelProvider implements IFontProvider {
        @Override
        public Font getFont(Object element) {
            if (unitMatcher != null) {
                IInstallableUnit unit = toInstallableUnit(element);
                if (unit != null && unitMatcher.match(unit)) {
                    return boldFont;
                }
            }
            return null;
        }
    };

    // windowbuilder wants this for some reason
    public AbstractInstallableUnitHierarchyView() {
    }

    @Override
    public void createPartControl(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        GridLayout gl_composite = new GridLayout(1, false);
        gl_composite.marginWidth = 0;
        gl_composite.marginHeight = 0;
        composite.setLayout(gl_composite);

        final InstallableUnitFilterComposite filterComposite = new InstallableUnitFilterComposite(composite,
                SWT.NONE);
        filterComposite.addFilterChangeListener(new IFilterChangeListener() {
            public void filterChanged(EventObject event) {
                unitMatcher = filterComposite.getMatcher();
                applyFilterJob.schedule(500L);
            }
        });
        filterComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

        SashForm sashForm = new SashForm(composite, SWT.NONE);
        sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

        Section hierarchySection = new Section(sashForm, Section.TITLE_BAR);
        hierarchySection.setText(getHierarchySectionTitle());

        ToolBar hierarchyToolBar = new ToolBar(hierarchySection, SWT.FLAT | SWT.RIGHT);
        hierarchySection.setTextClient(hierarchyToolBar);

        ToolBarManager hierarchyToolBarManager = new ToolBarManager(hierarchyToolBar);
        hierarchyToolBarManager.add(new Action("Expand All",
                ResourceManager.getPluginImageDescriptor("com.ifedorenko.p2browser", "icons/expandall.gif")) {
            public void run() {
                hierarchyTreeViewer.getTree().setRedraw(false);
                hierarchyTreeViewer.expandAll();
                hierarchyTreeViewer.getTree().setRedraw(true);
            };
        });
        hierarchyToolBarManager.add(new Action("Collapse All",
                ResourceManager.getPluginImageDescriptor("com.ifedorenko.p2browser", "icons/collapseall.gif")) {
            public void run() {
                hierarchyTreeViewer.getTree().setRedraw(false);
                hierarchyTreeViewer.collapseAll();
                hierarchyTreeViewer.expandToLevel(2);
                hierarchyTreeViewer.getTree().setRedraw(true);
            };
        });
        hierarchyToolBarManager.add(new Separator());
        filterHierarchyAction = new Action("Filter",
                ResourceManager.getPluginImageDescriptor("com.ifedorenko.p2browser", "icons/filter.gif")) {
            @Override
            public int getStyle() {
                return AS_CHECK_BOX;
            }

            public void run() {
                filterHierarchy = isChecked();
                applyHierachyFilter();
            };
        };
        filterHierarchyAction.setChecked(filterHierarchy);
        hierarchyToolBarManager.add(filterHierarchyAction);
        hierarchyToolBarManager.update(true);

        hierarchyTreeViewer = new TreeViewer(hierarchySection, SWT.BORDER | SWT.VIRTUAL);
        Tree hierarchyTree = hierarchyTreeViewer.getTree();
        hierarchySection.setClient(hierarchyTree);
        hierarchyTreeViewer.setUseHashlookup(true);
        hierarchyTreeViewer.setContentProvider(new InstallableUnitContentProvider(hierarchyTreeViewer) {
            @Override
            public Object[] getChildren(Object inputElement) {
                if (inputElement instanceof IGroupedInstallableUnits) {
                    IGroupedInstallableUnits metadata = (IGroupedInstallableUnits) inputElement;
                    return toViewNodes(metadata, metadata.getRootIncludedInstallableUnits());
                }
                return super.getChildren(inputElement);
            }
        });

        ILabelProvider labelProvider = new LabelProvider();

        hierarchyTreeViewer.setLabelProvider(labelProvider);

        Section listSection = new Section(sashForm, Section.TITLE_BAR);
        listSection.setText(getListSectionTitle());

        ToolBar listToolBar = new ToolBar(listSection, SWT.FLAT | SWT.RIGHT);
        listSection.setTextClient(listToolBar);
        ToolBarManager listToolbarManager = new ToolBarManager(listToolBar);
        Action sortListAction = new Action("Sort",
                ResourceManager.getPluginImageDescriptor("com.ifedorenko.p2browser", "icons/sort.gif")) {
            @Override
            public int getStyle() {
                return AS_CHECK_BOX;
            }

            @Override
            public void run() {
                sortList = isChecked();
                applyListFilter();
            }
        };
        sortListAction.setChecked(sortList);
        listToolbarManager.add(sortListAction);
        Action filterListAction = new Action("Filter",
                ResourceManager.getPluginImageDescriptor("com.ifedorenko.p2browser", "icons/filter.gif")) {
            @Override
            public int getStyle() {
                return AS_CHECK_BOX;
            }

            @Override
            public void run() {
                filterList = isChecked();
                applyListFilter();
            }
        };
        filterListAction.setChecked(filterList);
        listToolbarManager.add(filterListAction);
        listToolbarManager.update(true);

        listTableViewer = new TableViewer(listSection, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI);
        Table listTable = listTableViewer.getTable();
        listSection.setClient(listTable);

        listTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                Set<IInstallableUnit> units = toInstallableUnits(listTableViewer.getSelection());

                filterHierarchyAction.setEnabled(units == null);
                filterHierarchyAction.setChecked(units == null ? filterHierarchy : false);

                applyHierachyFilter(units);
            }
        });

        listTableViewer.setContentProvider(new IStructuredContentProvider() {
            @Override
            public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            }

            @Override
            public void dispose() {
            }

            @Override
            public Object[] getElements(Object inputElement) {
                if (inputElement instanceof List) {
                    List<?> elements = (List<?>) inputElement;

                    if (sortList) {
                        elements = new ArrayList<Object>(elements); // do not sort original collection
                        Collections.sort(elements, new Comparator<Object>() {
                            @Override
                            public int compare(Object o1, Object o2) {
                                // unchecked cast is on purpose, so we known when element type changes ;-)
                                IInstallableUnit u1 = (IInstallableUnit) o1;
                                IInstallableUnit u2 = (IInstallableUnit) o2;

                                return u1.getId().compareTo(u2.getId());
                            }
                        });
                    }
                    return elements.toArray();
                }
                return null;
            }
        });
        listTableViewer.setLabelProvider(labelProvider);

        listTableViewer.addFilter(new ViewerFilter() {
            @Override
            public boolean select(Viewer viewer, Object parentElement, Object element) {
                if (!filterList || unitMatcher == null) {
                    // no filter
                    return true;
                }

                IInstallableUnit unit = null;
                if (element instanceof IInstallableUnit) {
                    unit = (IInstallableUnit) element;
                }

                if (unit == null) {
                    return true;
                }

                return unitMatcher.match(unit);
            }
        });

        sashForm.setWeights(new int[] { 1, 1 });

        Font font = listTableViewer.getTable().getFont();
        FontData[] fontDatas = font.getFontData();
        for (FontData fontData : fontDatas) {
            fontData.setStyle(SWT.BOLD);
        }
        boldFont = new Font(getSite().getShell().getDisplay(), fontDatas);
    }

    String getListSectionTitle() {
        return "List section";
    }

    String getHierarchySectionTitle() {
        return "Hierarchy section";
    }

    @Override
    public void setFocus() {
        // Set the focus
    }

    public void setMetadata(IQueryable<IInstallableUnit> units, Collection<IInstallableUnit> roots) {
        IInstallableUnitHierarchyCalculator calculator = getCalculator(units, roots);

        run(calculator);
        dag = calculator.getHierarchy();

        setDependencyTree(new InstallableUnitDependencyTree(dag));
        listTableViewer.setInput(calculator.getList());
    }

    protected abstract IInstallableUnitHierarchyCalculator getCalculator(IQueryable<IInstallableUnit> units,
            Collection<IInstallableUnit> roots);

    void setDependencyTree(InstallableUnitDependencyTree dependencyTree) {
        hierarchyTreeViewer.getTree().setRedraw(false);
        hierarchyTreeViewer.setInput(dependencyTree);
        hierarchyTreeViewer.getTree().setItemCount(dependencyTree.getRootIncludedInstallableUnits().size());
        hierarchyTreeViewer.refresh();
        if (dependencyTree.size() < 100) {
            hierarchyTreeViewer.expandAll();
        } else {
            hierarchyTreeViewer.expandToLevel(2);
        }
        hierarchyTreeViewer.getTree().setRedraw(true);
    }

    void applyHierachyFilter() {
        applyHierachyFilter(toInstallableUnits(listTableViewer.getSelection()));
    }

    void applyHierachyFilter(Set<IInstallableUnit> units) {
        InstallableUnitDAG filteredDag = this.dag;

        if (units != null) {
            // apply right-pane selection filter
            filteredDag = filteredDag.filter(new InstallableUnitsMatcher(units), true);
        } else if (unitMatcher != null && filterHierarchy) {
            filteredDag = filteredDag.filter(unitMatcher, true);
        }

        setDependencyTree(new InstallableUnitDependencyTree(filteredDag));
    }

    Set<IInstallableUnit> toInstallableUnits(ISelection selection) {
        Set<IInstallableUnit> units = null;
        if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
            units = new HashSet<IInstallableUnit>();

            Iterator<?> iter = ((IStructuredSelection) selection).iterator();
            while (iter.hasNext()) {
                Object element = iter.next();
                if (element instanceof IInstallableUnit) {
                    units.add((IInstallableUnit) element);
                }
            }

            if (units.isEmpty()) {
                units = null;
            }
        }
        return units;
    }

    void applyListFilter() {
        listTableViewer.getTable().setRedraw(false);
        listTableViewer.refresh();
        listTableViewer.getTable().setRedraw(true);
    }

    protected void run(IRunnableWithProgress runnable) {
        try {
            getViewSite().getWorkbenchWindow().run(true, true, runnable);
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}