Package name.abuchen.portfolio.ui.util

Source Code of name.abuchen.portfolio.ui.util.ColumnViewerSorter$BeanComparator

package name.abuchen.portfolio.ui.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import name.abuchen.portfolio.model.Adaptor;

import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerColumn;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.Widget;

public final class ColumnViewerSorter extends ViewerComparator
{
    private static class ChainedComparator implements Comparator<Object>
    {
        private final List<Comparator<Object>> comparators;

        private ChainedComparator(List<Comparator<Object>> comparators)
        {
            this.comparators = comparators;
        }

        @Override
        public int compare(Object o1, Object o2)
        {
            for (Comparator<Object> c : comparators)
            {
                int result = c.compare(o1, o2);
                if (result != 0)
                    return result;
            }

            return 0;
        }
    }

    private static class BeanComparator implements Comparator<Object>
    {
        private final Class<?> clazz;
        private final Method method;
        private final int type;

        private BeanComparator(Class<?> clazz, String attribute)
        {
            Method readMethod = null;
            String camelCaseAttribute = Character.toUpperCase(attribute.charAt(0)) + attribute.substring(1);
            try
            {
                readMethod = clazz.getMethod("get" + camelCaseAttribute); //$NON-NLS-1$
            }
            catch (NoSuchMethodException e)
            {
                try
                {
                    readMethod = clazz.getMethod("is" + camelCaseAttribute); //$NON-NLS-1$
                }
                catch (NoSuchMethodException e1)
                {
                    throw new UnsupportedOperationException(e);
                }
            }

            this.clazz = clazz;
            this.method = readMethod;

            Class<?> returnType = method.getReturnType();

            if (returnType.equals(Object.class))
                type = 0;
            else if (returnType.isAssignableFrom(String.class))
                type = 1;
            else if (returnType.isAssignableFrom(Enum.class))
                type = 2;
            else if (returnType.isAssignableFrom(Integer.class) || returnType.isAssignableFrom(int.class))
                type = 3;
            else if (returnType.isAssignableFrom(Double.class) || returnType.isAssignableFrom(double.class))
                type = 4;
            else if (returnType.isAssignableFrom(Date.class))
                type = 5;
            else if (returnType.isAssignableFrom(Long.class) || returnType.isAssignableFrom(long.class))
                type = 6;
            else if (returnType.isAssignableFrom(Boolean.class) || returnType.isAssignableFrom(boolean.class))
                type = 7;
            else
                type = 0;
        }

        @Override
        public int compare(Object o1, Object o2)
        {
            Object object1 = Adaptor.adapt(clazz, o1);
            Object object2 = Adaptor.adapt(clazz, o2);

            if (object1 == null && object2 == null)
                return 0;
            else if (object1 == null)
                return -1;
            else if (object2 == null)
                return 1;

            try
            {
                Object attribute1 = method.invoke(object1);
                Object attribute2 = method.invoke(object2);

                if (attribute1 == null && attribute2 == null)
                    return 0;
                else if (attribute1 == null)
                    return -1;
                else if (attribute2 == null)
                    return 1;

                switch (type)
                {
                    case 1:
                        return ((String) attribute1).compareTo((String) attribute2);
                    case 2:
                        return ((Enum<?>) attribute2).name().compareTo(((Enum<?>) attribute2).name());
                    case 3:
                        return ((Integer) attribute1).compareTo((Integer) attribute2);
                    case 4:
                        return ((Double) attribute1).compareTo((Double) attribute2);
                    case 5:
                        return ((Date) attribute1).compareTo((Date) attribute2);
                    case 6:
                        return ((Long) attribute1).compareTo((Long) attribute2);
                    case 7:
                        return ((Boolean) attribute1).compareTo((Boolean) attribute2);
                    default:
                        return String.valueOf(attribute1).compareTo(String.valueOf(attribute2));
                }
            }
            catch (IllegalAccessException e)
            {
                throw new UnsupportedOperationException(e);
            }
            catch (InvocationTargetException e)
            {
                throw new UnsupportedOperationException(e);
            }
        }
    }

    public static ColumnViewerSorter create(Class<?> clazz, String... attributes)
    {
        List<Comparator<Object>> comparators = new ArrayList<Comparator<Object>>();

        for (String attribute : attributes)
            comparators.add(new BeanComparator(clazz, attribute));

        return new ColumnViewerSorter(comparators.size() == 1 ? comparators.get(0) : new ChainedComparator(comparators));
    }

    public static ColumnViewerSorter create(Comparator<Object> comparator)
    {
        return new ColumnViewerSorter(comparator);
    }

    private final Comparator<Object> comparator;

    private ColumnViewer columnViewer;
    private ViewerColumn viewerColumn;
    private int direction = SWT.DOWN;

    private ColumnViewerSorter(Comparator<Object> comparator)
    {
        this.comparator = comparator;
    }

    public int compare(Viewer viewer, Object element1, Object element2)
    {
        int dir = direction == SWT.DOWN ? 1 : -1;

        if (element1 == null)
            return element2 == null ? 0 : dir;
        if (element2 == null)
            return dir * -1;

        return dir * comparator.compare(element1, element2);
    }

    public void attachTo(Column column)
    {
        column.setSorter(this);
    }

    public void attachTo(Column column, int direction)
    {
        column.setSorter(this, direction);
    }

    public void attachTo(ColumnViewer viewer, ViewerColumn column)
    {
        attachTo(viewer, column, false);
    }

    public void attachTo(ColumnViewer viewer, ViewerColumn column, boolean makeDefault)
    {
        this.columnViewer = viewer;
        this.viewerColumn = column;

        Widget widget = null;

        if (column instanceof TableViewerColumn)
            widget = ((TableViewerColumn) column).getColumn();
        else if (column instanceof TreeViewerColumn)
            widget = ((TreeViewerColumn) column).getColumn();
        else
            throw new UnsupportedOperationException();

        widget.addListener(SWT.Selection, new Listener()
        {

            @Override
            public void handleEvent(Event event)
            {
                if (columnViewer.getComparator() != null)
                {
                    if (columnViewer.getComparator() == ColumnViewerSorter.this)
                    {
                        setSorter(direction == SWT.DOWN ? SWT.UP : SWT.DOWN);
                    }
                    else
                    {
                        setSorter(SWT.DOWN);
                    }
                }
                else
                {
                    setSorter(SWT.DOWN);
                }
            }
        });

        if (makeDefault)
            setSorter(direction);
    }

    /* package */void setSorter(int direction)
    {
        this.direction = direction;

        if (viewerColumn instanceof TableViewerColumn)
        {
            TableColumn c = ((TableViewerColumn) viewerColumn).getColumn();
            c.getParent().setSortColumn(c);
            c.getParent().setSortDirection(direction);
        }
        else if (viewerColumn instanceof TreeViewerColumn)
        {
            TreeColumn c = ((TreeViewerColumn) viewerColumn).getColumn();
            c.getParent().setSortColumn(c);
            c.getParent().setSortDirection(direction);
        }

        if (columnViewer.getComparator() == this)
            columnViewer.refresh();
        else
            columnViewer.setComparator(this);
    }

}
TOP

Related Classes of name.abuchen.portfolio.ui.util.ColumnViewerSorter$BeanComparator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.