| /******************************************************************************* |
| * Copyright (c) 2007, 2009 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.ui.internal.views.markers; |
| |
| import java.util.Comparator; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.views.markers.MarkerField; |
| import org.eclipse.ui.views.markers.MarkerItem; |
| |
| /** |
| * The MarkerComparator is the class that handles the comparison of markers for |
| * a specific content provider. |
| * |
| * @since 3.4 |
| * |
| */ |
| class MarkerComparator implements Comparator { |
| |
| private MarkerField category; |
| |
| // These fields are in sort order |
| private MarkerField[] fields; |
| /** |
| * Constant to indicate an ascending sort direction. |
| */ |
| public static final int ASCENDING = 1; |
| /** |
| * Constant to indicate an descending sort direction. |
| */ |
| public static final int DESCENDING = -1; |
| private static final String PRIMARY_SORT_FIELD_TAG = "PRIMARY_SORT_FIELD"; //$NON-NLS-1$ |
| |
| private static final String DESCENDING_FIELDS = "DESCENDING_FIELDS"; //$NON-NLS-1$ |
| |
| // The fields with reversed direction |
| HashSet descendingFields = new HashSet(); |
| |
| /** |
| * Create a new instance of the receiver categorised by categoryField |
| * |
| * @param categoryField |
| * May be <code>null/<code> |
| * @param mainFields in order of compare significance |
| */ |
| public MarkerComparator(MarkerField categoryField, MarkerField[] mainFields) { |
| category = categoryField; |
| fields = mainFields; |
| } |
| |
| /** |
| * Compare the two objects to see if they have the same category value |
| * |
| * @param object1 |
| * @param object2 |
| * @return int |
| * @see Comparable#compareTo(Object) |
| */ |
| public int compareCategory(Object object1, Object object2) { |
| if (category == null) |
| return 0; |
| return category.compare((MarkerItem) object1, (MarkerItem) object2); |
| } |
| |
| /** |
| * Comparator to compare the two MarkerEntry(s) to see if they have the same |
| * category value |
| * |
| * @return Comparator |
| */ |
| Comparator getCategoryComparator(){ |
| return new Comparator(){ |
| public int compare(Object o1, Object o2) { |
| return compareCategory(o1, o2); |
| } |
| }; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) |
| */ |
| public int compare(Object arg0, Object arg1) { |
| |
| // Sort by category first |
| int value = compareCategory(arg0, arg1); |
| if (value == 0) |
| value=compareFields(arg0, arg1); |
| |
| return value ; |
| } |
| |
| /** |
| * Compare the two objects by various fields |
| * |
| * @param item0 |
| * @param item1 |
| * @return int |
| */ |
| public int compareFields(Object item0, Object item1) { |
| int value=0; |
| for (int i = 0; i < fields.length; i++) { |
| if (descendingFields.contains(fields[i])){ |
| value = fields[i].compare((MarkerItem)item1,(MarkerItem)item0); |
| }else{ |
| value = fields[i].compare((MarkerItem)item0,(MarkerItem)item1); |
| }if (value != 0){ |
| break; |
| } |
| } |
| return value; |
| } |
| /** |
| * Comparator to compare the two MarkerEntry(s) by various fields |
| * |
| * @return Comparator |
| */ |
| Comparator getFieldsComparator(){ |
| return new Comparator(){ |
| public int compare(Object o1, Object o2) { |
| return compareFields(o1, o2); |
| } |
| }; |
| } |
| |
| /** |
| * Switch the priority of the field from ascending to descending or vice |
| * versa. |
| * |
| * @param field |
| */ |
| public void reversePriority(MarkerField field) { |
| if (descendingFields.remove(field)) |
| return; |
| descendingFields.add(field); |
| |
| } |
| |
| /** |
| * Set field to be the first sort field. |
| * |
| * @param field |
| */ |
| void setPrimarySortField(MarkerField field) { |
| if (fields[0] == field) { |
| reversePriority(field); |
| return; |
| } |
| int insertionIndex = 1; |
| MarkerField[] newFields = new MarkerField[fields.length]; |
| |
| newFields[0] = field; |
| for (int i = 0; i < newFields.length; i++) { |
| if (fields[i] == field) |
| continue; |
| newFields[insertionIndex] = fields[i]; |
| insertionIndex++; |
| } |
| |
| fields = newFields; |
| |
| } |
| |
| /** |
| * Restore the receiver's state from memento. |
| * |
| * @param memento |
| */ |
| void restore(IMemento memento) { |
| if (memento == null) |
| return; |
| |
| String primaryField = memento.getString(PRIMARY_SORT_FIELD_TAG); |
| if (primaryField == null |
| || primaryField.equals(MarkerSupportInternalUtilities |
| .getId(fields[0]))) |
| return; |
| for (int i = 1; i < fields.length; i++) { |
| if (MarkerSupportInternalUtilities.getId(fields[i]).equals( |
| primaryField)) { |
| setPrimarySortField(fields[i]); |
| break; |
| } |
| } |
| IMemento[] descending = memento.getChildren(DESCENDING_FIELDS); |
| |
| for (int i = 0; i < fields.length; i++) { |
| for (int j = 0; j < descending.length; j++) { |
| if (descending[j].getID().equals( |
| MarkerSupportInternalUtilities.getId(fields[i]))) { |
| descendingFields.add(fields[i]); |
| continue; |
| } |
| |
| } |
| } |
| |
| } |
| |
| /** |
| * Save the current sort field in the memento. |
| * |
| * @param memento |
| */ |
| void saveState(IMemento memento) { |
| memento.putString(PRIMARY_SORT_FIELD_TAG, |
| MarkerSupportInternalUtilities.getId(fields[0])); |
| Iterator descendingIterator = descendingFields.iterator(); |
| while (descendingIterator.hasNext()) { |
| memento.createChild(DESCENDING_FIELDS, |
| (MarkerSupportInternalUtilities |
| .getId((MarkerField) descendingIterator.next()))); |
| } |
| |
| } |
| |
| /** |
| * Get the field that is the main sort field |
| * |
| * @return MarkerField |
| */ |
| MarkerField getPrimarySortField() { |
| return fields[0]; |
| } |
| |
| /** |
| * Set the category field without changing other sort orders. |
| * @param category or <code>null</code> |
| */ |
| void setCategory(MarkerField category) { |
| this.category = category; |
| } |
| |
| } |