blob: cd2aa31e138804fef786e04ee42291b19c574843 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}