package de.is24.infrastructure.gridfs.http.rpm.version; import org.apache.commons.lang.StringUtils; import java.math.BigInteger; import java.util.Comparator; import java.util.Iterator; import java.util.List; public class RpmVersionSegmentComparator implements Comparator<List<String>> { @Override public int compare(List<String> o1, List<String> o2) { if ((o1 == null) || o1.isEmpty()) { return ((o2 == null) || o2.isEmpty()) ? 0 : -1; } if ((o2 == null) || o2.isEmpty()) { return 1; } return compareNonNullLists(o1, o2); } private int compareNonNullLists(final List<String> o1, final List<String> o2) { Iterator<String> iterator1 = o1.iterator(); Iterator<String> iterator2 = o2.iterator(); while (iterator1.hasNext() && iterator2.hasNext()) { String segment1 = iterator1.next(); String segment2 = iterator2.next(); // not-empty is always greater than empty if (!segment1.isEmpty() && segment2.isEmpty()) { return 1; } if (segment1.isEmpty() && !segment2.isEmpty()) { return -1; } int result = compareNonEmptySegments(segment1, segment2); if (result != 0) { return result; } } return compareSizeOfLists(o1, o2); } private int compareNonEmptySegments(final String segment1, final String segment2) { if (!(segment1.isEmpty() && segment2.isEmpty())) { int result = compareSegments(segment1, segment2); if (result == 0) { return 0; } else { return result; } } else { return 0; } } private int compareSizeOfLists(final List<String> o1, final List<String> o2) { // version with more segments than another greater if otherwise equal if (o1.size() == o2.size()) { return 0; } else { return (o1.size() > o2.size()) ? 1 : -1; } } private int compareSegments(final String segment1, final String segment2) { boolean isNumeric1 = StringUtils.isNumeric(segment1); boolean isNumeric2 = StringUtils.isNumeric(segment2); // numeric is always greater than non-numeric if (isNumeric1 && !isNumeric2) { return 1; } if (!isNumeric1 && isNumeric2) { return -1; } return compareStrings(segment1, segment2, isNumeric1, isNumeric2); } private int compareStrings(final String segment1, final String segment2, final boolean numeric1, final boolean numeric2) { int stringCompare = segment1.compareTo(segment2); if (stringCompare == 0) { return stringCompare; } else { if (numeric1 && numeric2) { return new BigInteger(segment1).compareTo(new BigInteger(segment2)); } else { return stringCompare; } } } }