/******************************************************************************* * Copyright (c) 2004, 2007 Boeing. * 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: * Boeing - initial API and implementation *******************************************************************************/ package org.eclipse.nebula.widgets.xviewer; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.StringTokenizer; import java.util.logging.Level; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.nebula.widgets.xviewer.core.model.SortDataType; import org.eclipse.nebula.widgets.xviewer.core.model.XViewerColumn; import org.eclipse.nebula.widgets.xviewer.util.Pair; import org.eclipse.nebula.widgets.xviewer.util.internal.XViewerLog; /** * XTreeSorter is equipped to: 1) Sort columns forward and backward by re-selecting the column 2) Sort by multiple * columns * * @author Donald G. Dunne */ public class XViewerSorter extends ViewerSorter { private final XViewer treeViewer; public final static SimpleDateFormat format10 = new SimpleDateFormat("MM/dd/yyyy"); public XViewerSorter(XViewer treeViewer) { super(); this.treeViewer = treeViewer; } @SuppressWarnings("unchecked") public int compare(Viewer viewer, Object o1, Object o2, int sortXColIndex) { if (treeViewer.getCustomizeMgr().isLoading()) { return 0; } List<XViewerColumn> sortXCols = treeViewer.getCustomizeMgr().getSortXCols(); if (sortXCols == null || sortXCols.isEmpty()) { return 0; } XViewerColumn sortXCol = sortXCols.get(sortXColIndex); try { int columnNum = treeViewer.getCustomizeMgr().getColumnNumFromXViewerColumn(sortXCol); String o1Str = treeViewer.getColumnText(o1, columnNum); Object obj1 = null; String o2Str = treeViewer.getColumnText(o2, columnNum); Object obj2 = null; IBaseLabelProvider labelProvider = treeViewer.getLabelProvider(); if (labelProvider instanceof IXViewerLabelProvider) { obj1 = ((IXViewerLabelProvider) labelProvider).getBackingData(o1, sortXCol, columnNum); obj2 = ((IXViewerLabelProvider) labelProvider).getBackingData(o2, sortXCol, columnNum); } int compareInt = 0; if (o1Str == null) { compareInt = -1; } else if (o2Str == null) { compareInt = 1; } else if (sortXCol.getSortDataType() == SortDataType.Date) { compareInt = getCompareForDate(o1Str, obj1, o2Str, obj2); } else if (sortXCol.getSortDataType() == SortDataType.Percent) { compareInt = getCompareForPercent(o1Str, o2Str); } else if (sortXCol.getSortDataType() == SortDataType.Float) { compareInt = getCompareForFloat(o1Str, o2Str); } else if (sortXCol.getSortDataType() == SortDataType.Integer) { compareInt = getCompareForInteger(o1Str, o2Str); } else if (sortXCol.getSortDataType() == SortDataType.Long) { compareInt = getCompareForLong(o1Str, o2Str); } else if (sortXCol.getSortDataType() == SortDataType.Paragraph_Number) { compareInt = paragraphNumberCompare(o1Str, o2Str); } else { compareInt = getComparator().compare(o1Str, o2Str); } return getCompareBasedOnDirection(sortXCol, compareInt, viewer, o1, o2, sortXColIndex); } catch (Exception ex) { XViewerLog.log(Activator.class, Level.SEVERE, ex); } return 0; } @Override public int compare(Viewer viewer, Object o1, Object o2) { return compare(viewer, o1, o2, 0); } public int paragraphNumberCompare(String s1, String s2) { StringTokenizer st1 = new StringTokenizer(s1, "."); StringTokenizer st2 = new StringTokenizer(s2, "."); while (st1.hasMoreTokens() && st2.hasMoreTokens()) { String t1 = st1.nextToken(); String t2 = st2.nextToken(); int result; try { Integer i1 = Integer.valueOf(t1); Integer i2 = Integer.valueOf(t2); result = i1.compareTo(i2); } catch (NumberFormatException e) { result = t1.compareTo(t2); } if (result != 0) { return result; } } return s1.compareTo(s2); } public int getCompareBasedOnDirection(XViewerColumn sortXCol, int compareInt, Viewer viewer, Object o1, Object o2, int sortXColIndex) { List<XViewerColumn> sortXCols = treeViewer.getCustomizeMgr().getSortXCols(); int returnInt = (sortXCol.isSortForward() ? 1 : -1) * compareInt; if (returnInt == 0 && sortXCols.size() > sortXColIndex + 1) { returnInt = compare(viewer, o1, o2, (sortXColIndex + 1)); } return returnInt; } @SuppressWarnings("unchecked") public int getCompareForFloat(String float1, String float2) { double float1Float = 0; boolean float1Exception = false; try { float1Float = new Double(float1).doubleValue(); } catch (NumberFormatException ex) { float1Exception = true; } double float2Float = 0; boolean float2Exception = false; try { float2Float = new Double(float2).doubleValue(); } catch (NumberFormatException ex) { float2Exception = true; } int toReturn = 0; if (float1Exception && float2Exception) { toReturn = getComparator().compare(float1, float2); } else if (float1Exception && !float2Exception) { toReturn = -1; } else if (!float1Exception && float2Exception) { toReturn = 1; } else { toReturn = getCompareForFloat(float1Float, float2Float); } return toReturn; } @SuppressWarnings("unchecked") public int getCompareForInteger(String int1, String int2) { int int1Integer = 0; boolean int1Exception = false; try { int1Integer = Integer.valueOf(int1).intValue(); } catch (NumberFormatException ex) { int1Exception = true; } int int2Integer = 0; boolean int2Exception = false; try { int2Integer = Integer.valueOf(int2).intValue(); } catch (NumberFormatException ex) { int2Exception = true; } int toReturn = 0; if (int1Exception && int2Exception) { toReturn = getComparator().compare(int1, int2); } else if (int1Exception && !int2Exception) { toReturn = -1; } else if (!int1Exception && int2Exception) { toReturn = 1; } else { toReturn = getCompareForInteger(int1Integer, int2Integer); } return toReturn; } @SuppressWarnings("unchecked") public int getCompareForLong(String long1, String long2) { long long1Long = 0; boolean long1Exception = false; try { long1Long = Long.valueOf(long1).longValue(); } catch (NumberFormatException ex) { long1Exception = true; } long long2Integer = 0; boolean long2Exception = false; try { long2Integer = Long.valueOf(long2).longValue(); } catch (NumberFormatException ex) { long2Exception = true; } int toReturn = 0; if (long1Exception && long2Exception) { toReturn = getComparator().compare(long1, long2); } else if (long1Exception && !long2Exception) { toReturn = -1; } else if (!long1Exception && long2Exception) { toReturn = 1; } else { toReturn = getCompareForLong(long1Long, long2Integer); } return toReturn; } public static int getCompareForFloat(double float1, double float2) { if (float1 == float2) { return 0; } else if (float1 < float2) { return -1; } else if (float2 < float1) { return 1; } else { return 0; } } public static int getCompareForInteger(int int1, int int2) { if (int1 == int2) { return 0; } else if (int1 < int2) { return -1; } else if (int2 < int1) { return 1; } else { return 0; } } public static int getCompareForLong(long long1, long long2) { if (long1 == long2) { return 0; } else if (long1 < long2) { return -1; } else if (long2 < long1) { return 1; } else { return 0; } } public int getCompareForDate(String date1, Object obj1, String date2, Object obj2) { Date date1Date = null; if (obj1 != null && obj1 instanceof Date) { date1Date = (Date) obj1; } Date date2Date = null; if (obj2 != null && obj2 instanceof Date) { date2Date = (Date) obj2; } if (date1Date != null && date2Date != null) { return getCompareForDate(date1Date, date2Date); } else if (obj1 == null && obj2 == null) { return 0; } else if (obj1 == null) { return -1; } else { return 1; } } public static Pair<Date, Date> parseDatePair(String date1, String date2) { Pair<Date, Date> datePair = new Pair<Date, Date>(null, null); DateFormat format; if (date1.length() == 10) { format = format10; } else { format = new SimpleDateFormat(); } try { Date date = format.parse(date1); datePair.setFirst(date); } catch (ParseException ex) { try { Date date = new SimpleDateFormat().parse(date1); datePair.setFirst(date); } catch (ParseException ex2) { // do nothing; } } try { Date date = format.parse(date2); datePair.setSecond(date); } catch (ParseException ex) { try { Date date = DateFormat.getInstance().parse(date2); datePair.setSecond(date); } catch (ParseException ex2) { // do nothing } } return datePair; } public int getCompareForDate(Date date1, Date date2) { return date1.compareTo(date2); } @SuppressWarnings("unchecked") public int getCompareForPercent(String percent1, String percent2) { int percent1Int = 0; boolean percent1Exception = false; try { percent1Int = Integer.valueOf(percent1).intValue(); } catch (NumberFormatException ex) { percent1Exception = true; } int percent2Int = 0; boolean percent2Exception = false; try { percent2Int = Integer.valueOf(percent2).intValue(); } catch (NumberFormatException ex) { percent2Exception = true; } int toReturn = 0; if (percent1Exception && percent2Exception) { toReturn = getComparator().compare(percent1, percent2); } else if (percent1Exception && !percent2Exception) { toReturn = -1; } else if (!percent1Exception && percent2Exception) { toReturn = 1; } else { toReturn = getCompareForPercent(percent1Int, percent2Int); } return toReturn; } public int getCompareForPercent(int percent1, int percent2) { int compareInt = 0; if (percent1 == percent2) { compareInt = 0; } else if (percent1 == 0) { compareInt = -1; } else if (percent2 == 0) { compareInt = 1; } else if (percent1 == 100) { compareInt = 1; } else if (percent2 == 100) { compareInt = -1; } else { compareInt = getCompareForInteger(percent1, percent2); } return compareInt; } }