1package junit.framework;
2
3public class ComparisonCompactor {
4
5    private static final String ELLIPSIS = "...";
6    private static final String DELTA_END = "]";
7    private static final String DELTA_START = "[";
8
9    private int fContextLength;
10    private String fExpected;
11    private String fActual;
12    private int fPrefix;
13    private int fSuffix;
14
15    public ComparisonCompactor(int contextLength, String expected, String actual) {
16        fContextLength = contextLength;
17        fExpected = expected;
18        fActual = actual;
19    }
20
21    public String compact(String message) {
22        if (fExpected == null || fActual == null || areStringsEqual()) {
23            return Assert.format(message, fExpected, fActual);
24        }
25
26        findCommonPrefix();
27        findCommonSuffix();
28        String expected = compactString(fExpected);
29        String actual = compactString(fActual);
30        return Assert.format(message, expected, actual);
31    }
32
33    private String compactString(String source) {
34        String result = DELTA_START + source.substring(fPrefix, source.length() - fSuffix + 1) + DELTA_END;
35        if (fPrefix > 0) {
36            result = computeCommonPrefix() + result;
37        }
38        if (fSuffix > 0) {
39            result = result + computeCommonSuffix();
40        }
41        return result;
42    }
43
44    private void findCommonPrefix() {
45        fPrefix = 0;
46        int end = Math.min(fExpected.length(), fActual.length());
47        for (; fPrefix < end; fPrefix++) {
48            if (fExpected.charAt(fPrefix) != fActual.charAt(fPrefix)) {
49                break;
50            }
51        }
52    }
53
54    private void findCommonSuffix() {
55        int expectedSuffix = fExpected.length() - 1;
56        int actualSuffix = fActual.length() - 1;
57        for (; actualSuffix >= fPrefix && expectedSuffix >= fPrefix; actualSuffix--, expectedSuffix--) {
58            if (fExpected.charAt(expectedSuffix) != fActual.charAt(actualSuffix)) {
59                break;
60            }
61        }
62        fSuffix = fExpected.length() - expectedSuffix;
63    }
64
65    private String computeCommonPrefix() {
66        return (fPrefix > fContextLength ? ELLIPSIS : "") + fExpected.substring(Math.max(0, fPrefix - fContextLength), fPrefix);
67    }
68
69    private String computeCommonSuffix() {
70        int end = Math.min(fExpected.length() - fSuffix + 1 + fContextLength, fExpected.length());
71        return fExpected.substring(fExpected.length() - fSuffix + 1, end) + (fExpected.length() - fSuffix + 1 < fExpected.length() - fContextLength ? ELLIPSIS : "");
72    }
73
74    private boolean areStringsEqual() {
75        return fExpected.equals(fActual);
76    }
77}
78