/******************************************************************************* * Copyright (c) 2004, 2009 Tasktop Technologies and others. * 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: * Tasktop Technologies - initial API and implementation * Frank Becker - improvements for bug 231336 * Julio Gesser - fixes for bug 303509 *******************************************************************************/ package org.eclipse.mylyn.internal.tasks.ui.util; import java.util.Comparator; import java.util.Date; import org.eclipse.mylyn.internal.tasks.ui.util.SortCriterion.SortKey; import org.eclipse.mylyn.internal.tasks.ui.views.TaskKeyComparator; import org.eclipse.mylyn.tasks.core.IRepositoryElement; import org.eclipse.mylyn.tasks.core.ITask; import org.eclipse.mylyn.tasks.core.data.TaskAttribute; import org.eclipse.ui.IMemento; /** * @author Mik Kersten * @author Frank Becker */ public class TaskComparator implements Comparator<ITask> { private final SortCriterion[] sortCriteria; public static final int DEFAULT_SORT_DIRECTION = 1; private static final SortKey DEFAULT_SORT_INDEX = SortKey.PRIORITY; private static final SortKey DEFAULT_SORT_INDEX2 = SortKey.RANK; private static final SortKey DEFAULT_SORT_INDEX3 = SortKey.DATE_CREATED; private static final String MEMENTO_KEY_SORT = "sort"; //$NON-NLS-1$ /** * Return a array of values to pass to taskKeyComparator.compare() for sorting * * @param element * the element to sort * @return String array[component, taskId, summary] */ public static String[] getSortableFromElement(IRepositoryElement element) { final String a[] = new String[] { "", null, element.getSummary() }; //$NON-NLS-1$ if (element instanceof ITask) { ITask task1 = (ITask) element; if (task1.getTaskKey() != null) { a[1] = task1.getTaskKey(); } } return a; } private final TaskKeyComparator taskKeyComparator = new TaskKeyComparator(); public static final int CRITERIA_COUNT = SortKey.values().length - 1; public TaskComparator() { sortCriteria = new SortCriterion[CRITERIA_COUNT]; for (int index = 0; index < CRITERIA_COUNT; index++) { sortCriteria[index] = new SortCriterion(); } sortCriteria[0].setKey(DEFAULT_SORT_INDEX); sortCriteria[1].setKey(DEFAULT_SORT_INDEX2); sortCriteria[2].setKey(DEFAULT_SORT_INDEX3); } public int compare(ITask element1, ITask element2) { for (SortCriterion key : sortCriteria) { int result; switch (key.getKey()) { case DATE_CREATED: result = sortByDate(element1, element2, key.getDirection()); break; case RANK: result = sortByRank(element1, element2, key.getDirection()); break; case PRIORITY: result = sortByPriority(element1, element2, key.getDirection()); break; case SUMMARY: result = sortBySummary(element1, element2, key.getDirection()); break; case TASK_ID: result = sortByID(element1, element2, key.getDirection()); break; case TASK_TYPE: result = compare(element1.getTaskKind(), element2.getTaskKind(), key.getDirection()); break; case DUE_DATE: result = sortByDueDate(element1, element2, key.getDirection()); break; case MODIFICATION_DATE: result = sortByModificationDate(element1, element2, key.getDirection()); break; default: // NONE return 0; } if (result != 0) { return result; } } return 0; } public SortCriterion getSortCriterion(int index) { return sortCriteria[index]; } public void restoreState(IMemento memento) { if (memento != null) { for (int index = 0; index < CRITERIA_COUNT; index++) { IMemento child = memento.getChild(MEMENTO_KEY_SORT + index); if (child != null && sortCriteria[index] != null) { sortCriteria[index].restoreState(child); } } } } public void saveState(IMemento memento) { if (memento != null) { for (int index = 0; index < CRITERIA_COUNT; index++) { IMemento child = memento.createChild(MEMENTO_KEY_SORT + index); if (child != null && sortCriteria[index] != null) { sortCriteria[index].saveState(child); } } } } private int sortByDate(ITask element1, ITask element2, int sortDirection) { Date date1 = element1.getCreationDate(); Date date2 = element2.getCreationDate(); if (date1 == null) { return (date2 != null) ? sortDirection : 0; } else if (date2 == null) { return -sortDirection; } return sortDirection * date1.compareTo(date2); } private int sortByDueDate(ITask element1, ITask element2, int sortDirection) { Date date1 = element1.getDueDate(); Date date2 = element2.getDueDate(); return compare(date1, date2, sortDirection); } private int sortByModificationDate(ITask element1, ITask element2, int sortDirection) { Date date1 = element1.getModificationDate(); Date date2 = element2.getModificationDate(); return compare(date1, date2, sortDirection); } private <T> int compare(Comparable<T> key1, T key2, int sortDirection) { if (key1 == null) { return (key2 != null) ? sortDirection : 0; } else if (key2 == null) { return -sortDirection; } return sortDirection * key1.compareTo(key2); } private int sortByID(ITask element1, ITask element2, int sortDirection) { String key1 = element1.getTaskKey(); String key2 = element2.getTaskKey(); if (key1 == null) { return (key2 != null) ? sortDirection : 0; } else if (key2 == null) { return -sortDirection; } return sortDirection * taskKeyComparator.compare2(key1, key2); } private int sortByRank(ITask element1, ITask element2, int sortDirection) { if (element1.getConnectorKind() != null && element2.getConnectorKind() != null && element1.getConnectorKind().equals(element2.getConnectorKind())) { // only compare rank of elements from the same connector if (element1.getRepositoryUrl() != null && element2.getRepositoryUrl() != null && element1.getRepositoryUrl().equals(element2.getRepositoryUrl())) { // only compare the rank of elements in the same repository String rankString1 = element1.getAttribute(TaskAttribute.RANK); String rankString2 = element2.getAttribute(TaskAttribute.RANK); try { Double rank1 = rankString1 == null || rankString1.length() == 0 ? Double.valueOf(0) : Double.valueOf(rankString1); Double rank2 = rankString2 == null || rankString2.length() == 0 ? Double.valueOf(0) : Double.valueOf(rankString2); return compare(rank1, rank2, sortDirection); } catch (NumberFormatException e) { // ignore, means that there is no rank on one of the elements } } } return 0; } private int sortByPriority(ITask element1, ITask element2, int sortDirection) { return sortDirection * element1.getPriority().compareToIgnoreCase(element2.getPriority()); } private int sortBySummary(ITask element1, ITask element2, int sortDirection) { String key1 = element1.getSummary(); String key2 = element2.getSummary(); if (key1 == null) { return (key2 != null) ? sortDirection : 0; } else if (key2 == null) { return -sortDirection; } return sortDirection * key1.compareToIgnoreCase(key2); } }