001    package junit.framework;
002    
003    public class ComparisonCompactor {
004    
005        private static final String ELLIPSIS = "...";
006        private static final String DELTA_END = "]";
007        private static final String DELTA_START = "[";
008    
009        private int fContextLength;
010        private String fExpected;
011        private String fActual;
012        private int fPrefix;
013        private int fSuffix;
014    
015        public ComparisonCompactor(int contextLength, String expected, String actual) {
016            fContextLength = contextLength;
017            fExpected = expected;
018            fActual = actual;
019        }
020    
021        @SuppressWarnings("deprecation")
022        public String compact(String message) {
023            if (fExpected == null || fActual == null || areStringsEqual()) {
024                return Assert.format(message, fExpected, fActual);
025            }
026    
027            findCommonPrefix();
028            findCommonSuffix();
029            String expected = compactString(fExpected);
030            String actual = compactString(fActual);
031            return Assert.format(message, expected, actual);
032        }
033    
034        private String compactString(String source) {
035            String result = DELTA_START + source.substring(fPrefix, source.length() - fSuffix + 1) + DELTA_END;
036            if (fPrefix > 0) {
037                result = computeCommonPrefix() + result;
038            }
039            if (fSuffix > 0) {
040                result = result + computeCommonSuffix();
041            }
042            return result;
043        }
044    
045        private void findCommonPrefix() {
046            fPrefix = 0;
047            int end = Math.min(fExpected.length(), fActual.length());
048            for (; fPrefix < end; fPrefix++) {
049                if (fExpected.charAt(fPrefix) != fActual.charAt(fPrefix)) {
050                    break;
051                }
052            }
053        }
054    
055        private void findCommonSuffix() {
056            int expectedSuffix = fExpected.length() - 1;
057            int actualSuffix = fActual.length() - 1;
058            for (; actualSuffix >= fPrefix && expectedSuffix >= fPrefix; actualSuffix--, expectedSuffix--) {
059                if (fExpected.charAt(expectedSuffix) != fActual.charAt(actualSuffix)) {
060                    break;
061                }
062            }
063            fSuffix = fExpected.length() - expectedSuffix;
064        }
065    
066        private String computeCommonPrefix() {
067            return (fPrefix > fContextLength ? ELLIPSIS : "") + fExpected.substring(Math.max(0, fPrefix - fContextLength), fPrefix);
068        }
069    
070        private String computeCommonSuffix() {
071            int end = Math.min(fExpected.length() - fSuffix + 1 + fContextLength, fExpected.length());
072            return fExpected.substring(fExpected.length() - fSuffix + 1, end) + (fExpected.length() - fSuffix + 1 < fExpected.length() - fContextLength ? ELLIPSIS : "");
073        }
074    
075        private boolean areStringsEqual() {
076            return fExpected.equals(fActual);
077        }
078    }