ShortNameComparator.java
- package emissary.util;
- import emissary.core.Family;
- import emissary.core.IBaseDataObject;
- import org.apache.commons.lang3.Validate;
- import java.io.Serializable;
- import java.util.Comparator;
- /**
- * Allow a Collection or Array of IBaseDataObject to be sorted by shortName such that all attachments come in order and
- * all parents are immediately followed by their children and all siblings are in numerical (i.e. not string) order.
- */
- public class ShortNameComparator implements Comparator<IBaseDataObject>, Serializable {
- // Serializable
- static final long serialVersionUID = -7621558910791975422L;
- @Override
- public int compare(IBaseDataObject obj1, IBaseDataObject obj2) {
- Validate.isTrue(obj1 != null, "Required: obj1 != null");
- Validate.isTrue(obj2 != null, "Required: obj2 != true");
- String s1 = obj1.shortName();
- String s2 = obj2.shortName();
- int index1 = s1.indexOf(Family.SEP);
- int index2 = s2.indexOf(Family.SEP);
- // Loop through each level in obj1's shortName.
- while (index1 != -1) {
- // If obj1's shortName has more levels than obj2's shortName then obj1 > obj2.
- if (index2 == -1) {
- return 1;
- }
- // Get start character of level.
- index1 += Family.SEP.length();
- index2 += Family.SEP.length();
- // Get character length of level.
- final int nextIndex1 = s1.indexOf(Family.SEP, index1);
- final int nextIndex2 = s2.indexOf(Family.SEP, index2);
- final int length1 = ((nextIndex1 < 0) ? s1.length() : nextIndex1) - index1;
- final int length2 = ((nextIndex2 < 0) ? s2.length() : nextIndex2) - index2;
- // If the obj1's level and obj2's level are the same, then go to the next level.
- if (length1 == length2 && s1.regionMatches(index1, s2, index2, length1)) {
- index1 = nextIndex1;
- index2 = nextIndex2;
- continue;
- }
- // Otherwise, try comparing the levels as integers.
- try {
- int int1 = Integer.parseInt(s1, index1, index1 + length1, 10);
- int int2 = Integer.parseInt(s2, index2, index2 + length2, 10);
- return int1 - int2;
- } catch (NumberFormatException e) {
- // Otherwise, compare the levels as strings.
- final String substring1 = s1.substring(index1, index1 + length1);
- final String substring2 = s2.substring(index2, index2 + length2);
- return substring1.compareTo(substring2);
- }
- }
- // If obj1's shortName has fewer levels than obj2's shortName then obj1 < obj2.
- if (index2 != -1) {
- return -1;
- }
- // Otherwise, obj1 and obj2 compare as equivalent
- return 0;
- }
- }