static List<Message> sortMessages(List<Message> messages) {
List<Message> sorted = Lists.newArrayList(messages);
Collections.sort(sorted, new Comparator<Message>() {
public int compare(Message a, Message b) {
MessagePart a0 = firstPartOf(a);
MessagePart b0 = firstPartOf(b);
InputSource aSrc = toInputSource(a0), bSrc = toInputSource(b0);
// Compure by source first.
if (aSrc != null && bSrc != null) {
int delta = aSrc.getUri().compareTo(bSrc.getUri());
if (delta != 0) { return delta; }
}
// Sort positionless parts after ones with a position.
long aSPos = Integer.MAX_VALUE + 1L, aEPos = Integer.MAX_VALUE + 1L;
long bSPos = Integer.MAX_VALUE + 1L, bEPos = Integer.MAX_VALUE + 1L;
if (a0 instanceof FilePosition) {
FilePosition pos = (FilePosition) a0;
aSPos = pos.startCharInFile();
aEPos = pos.endCharInFile();
} else if (a0 instanceof InputSource) {
// sort file level messages before messages within file
aSPos = aEPos = -1;
}
if (b0 instanceof FilePosition) {
FilePosition pos = (FilePosition) b0;
bSPos = pos.startCharInFile();
bEPos = pos.endCharInFile();
} else if (b0 instanceof InputSource) {
// sort file level messages before messages within file
bSPos = bEPos = -1;
}
int delta = Long.signum(aSPos - bSPos);
if (delta != 0) { return delta; }
delta = Long.signum(aEPos - bEPos);
if (delta != 0) { return delta; }
StringBuilder aBuf = new StringBuilder(), bBuf = new StringBuilder();
MessageContext mc = new MessageContext();
try {
a0.format(mc, aBuf);
b0.format(mc, bBuf);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
return aBuf.toString().compareTo(bBuf.toString());
}