/*
* Created on Nov 12, 2003
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package com.idega.block.datareport.util;
import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;
/*
* A Comparator for ReportableFields, used to sort ReportableData by one or more ReportableFields.
* The default comparisons works as follows.
* If a field value is a String containing a number, the numbers are used for the comparison. if the field is a String starting with a number and a whitespace,
* first the String after the whitespace is compared, then the number before the whitespace. In other cases the comparison is alphanumerical using
* icelandic locale.
* @author jonas
*/
public class FieldsComparator implements Comparator {
/**
* Constructs a FieldsComparator that compares ReportableData objects using the given fields,
* comparing each of the fields using one of the given comparators
* @param reportableFields The fields to use for comparing
* @param comparators The comparators to use, array must be same length as <code>reportableFields</code> array.
* The i-th Comparator is used to compare the i-th ReportableField. If the i-th is <code>null</code>, then
* default comparison is used (same as if other constructor was used).
*/
public FieldsComparator(ReportableField[] reportableFields, Comparator[] comparators) {
this._reportableFields = reportableFields;
this._comparators = comparators;
}
/**
* Constructs a FieldsComparator that compares ReportableData objects using the given fields.
* @param reportableFields The fields to use for comparing
*/
public FieldsComparator(ReportableField[] reportableFields) {
this._reportableFields = reportableFields;
this._comparators = null;
}
public int compare(Object o1, Object o2) {
if(o1==o2) {
return 0;
}
ReportableData data1 = (ReportableData) o1;
ReportableData data2 = (ReportableData) o2;
if(data1==null) {
return -1;
} else if (data2==null) {
return 1;
}
int count = this._reportableFields.length;
for(int i=0; i<count; i++) {
ReportableField field = this._reportableFields[i];
Object fieldValue1 = data1.getFieldValue(field);
Object fieldValue2 = data2.getFieldValue(field);
if(fieldValue1==fieldValue2) {
continue;
}
if(fieldValue1==null) {
return -1;
} else if(fieldValue2==null) {
return 1;
}
int comp;
if(this._comparators == null || this._comparators[i]==null) {
if(fieldValue1 instanceof String) {
// the two fieldvalues are always of the same type
comp = defaultStringCompare((String) fieldValue1, (String) fieldValue2);
} else {
comp = this._collator.compare(fieldValue1, fieldValue2);
}
} else {
comp = this._comparators[i].compare(fieldValue1, fieldValue2);
}
if(comp!=0) {
return comp;
}
}
return 0;
}
private int defaultStringCompare(String str0, String str1) {
int comp = 0;
int i1 = getInt(str0);
int i2 = getInt(str1);
if(i1!=-1 && i2!=-1) {
// found numbers to compare, use them
int dstr = this._collator.compare(getStringAfterInt(str0), getStringAfterInt(str1));
comp = dstr==0?(i1-i2):dstr;
} else {
comp = this._collator.compare(str0, str1);
}
return comp;
}
private int getInt(String str) {
try {
int val = Integer.parseInt(str);
return val;
} catch(NumberFormatException e) {
// don't care, continue searching for int
}
int i = str.indexOf(" ");
String c1;
if(i==-1) {
c1 = str;
} else {
c1 = str.substring(0, i);
}
try {
return Integer.parseInt(c1);
} catch(Exception e) {
//e.printStackTrace();
return -1;
}
}
private String getStringAfterInt(String str) {
int i = str.indexOf(" ");
return str.substring(i+1);
}
private ReportableField[] _reportableFields;
private Comparator[] _comparators;
private Collator _collator = Collator.getInstance(new Locale("is","IS"));
}