package org.limewire.ui.swing.search.resultpanel; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.limewire.inject.LazySingleton; @LazySingleton public class SearchResultTruncatorImpl implements SearchResultTruncator { private static final String SINGLE_SPACE = " "; private static final String EMPTY_STRING = ""; private static final String OPEN_TAG = "<b>"; private static final String CLOSE_TAG = "</b>"; private static final String ELLIPSIS = "..."; private static final int ELLIPSIS_SHRINK_INCREMENT = ELLIPSIS.length() + 1; private final Matcher findHTMLMinusBoldTags; private final Matcher findMultipleWhitespaceChars; private final Matcher findWhitespaceMinusSpaceChars; public SearchResultTruncatorImpl() { Pattern patternHTMLMinusBoldTags = Pattern.compile("[<][/]?[\\w =\":#&&[^b]]*[>]"); findHTMLMinusBoldTags = patternHTMLMinusBoldTags.matcher(""); Pattern patternMultipleWhitespaceChars = Pattern.compile("[\\s]++"); findMultipleWhitespaceChars = patternMultipleWhitespaceChars.matcher(""); Pattern patternWhitespaceMinusSpaceChars = Pattern.compile("[\\s&&[^ ]]"); findWhitespaceMinusSpaceChars = patternWhitespaceMinusSpaceChars.matcher(""); } @Override public String truncateHeading(String headingText, int visibleWidthPixels, FontWidthResolver resolver) { //Strip HTML characters *except* <b>bold-wrapped</b> strings headingText = replaceAll(findHTMLMinusBoldTags, headingText, EMPTY_STRING); if (resolver.getPixelWidth(headingText) <= visibleWidthPixels) { return headingText; } //Strip multiple whitespace characters (spaces, \r, \n, \t) and embedded whitespace characters String truncated = replaceAll(findMultipleWhitespaceChars, headingText, SINGLE_SPACE); truncated = replaceAll(findWhitespaceMinusSpaceChars, truncated, EMPTY_STRING); do { if (truncated.length() < ELLIPSIS_SHRINK_INCREMENT) { break; } if (getEndEdge(truncated) >= (truncated.length() - (truncated.contains(ELLIPSIS) ? ELLIPSIS.length() : 0))) { truncated = ELLIPSIS + truncated.substring(ELLIPSIS_SHRINK_INCREMENT); } else if (getLeadEdge(truncated) >= 0) { truncated = truncated.substring(0, truncated.length() - ELLIPSIS_SHRINK_INCREMENT) + ELLIPSIS; } } while (resolver.getPixelWidth(truncated) > visibleWidthPixels); return truncated; } private String replaceAll(Matcher pattern, String source, String replacement) { return pattern.reset(source).replaceAll(replacement); } private int getLeadEdge(String headingText) { int indexOf = headingText.indexOf(OPEN_TAG); return indexOf == -1 ? 0 : indexOf; } private int getEndEdge(String headingText) { int closeIndex = headingText.indexOf(CLOSE_TAG); return closeIndex == -1 ? 0 : closeIndex + CLOSE_TAG.length(); } }