package org.limewire.ui.swing.search.resultpanel.list;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.limewire.logging.Log;
import org.limewire.logging.LogFactory;
import org.limewire.util.Objects;
class SearchHighlightUtil {
private static final Log LOG = LogFactory.getLog(SearchHighlightUtil.class);
private final StringBuilder builderBuffer = new StringBuilder();
private final Matcher matcher;
SearchHighlightUtil(String search) {
// Create literal string with escaped regex characters.
String literalSearch = createLiteralSearch(Objects.nonNull(search, "search"));
// Create pattern to match on word boundary, and match content.
Pattern pattern = Pattern.compile("\\b(" + literalSearch + ")", Pattern.CASE_INSENSITIVE);
matcher = pattern.matcher("");
}
/**
* Returns a string that highlights the specified search text within the
* specified content. Highlights are indicated using HTML <b> tags.
* Multiple search words are separated by space characters; matches occur
* on word boundaries.
*/
public String highlight(String content) {
if (content == null) {
return "";
}
matcher.reset(content);
builderBuffer.setLength(0);
int index = 0;
while (matcher.find()) {
int startIndex = matcher.start();
builderBuffer.append(content.substring(index, startIndex));
String word = matcher.group();
builderBuffer.append("<b>").append(word).append("</b>");
index = matcher.end();
LOG.debugf("Start: {0} url: {1} end: {2}", startIndex, word, matcher.end());
}
if (builderBuffer.length() > 0) {
builderBuffer.append(content.substring(index));
return builderBuffer.toString();
}
return content;
}
/**
* Creates literal string for use in the highlight pattern. The method
* splits the specified search string into space-separated tokens, quotes
* each token to escape regex characters, and inserts an OR operator
* between each token. Zero-length tokens caused by consecutive space
* characters are ignored.
*/
private static String createLiteralSearch(String search) {
// Split search string into space-separated tokens.
String[] tokens = search.split(" ");
// Build literal string.
StringBuilder bldr = new StringBuilder();
for (String token : tokens) {
if (token.length() > 0) {
// Precede each token with OR operator.
if (bldr.length() > 0) {
bldr.append("|");
}
// Append quoted token to result.
String literal = Pattern.quote(token);
bldr.append(literal);
}
}
// Return result.
return bldr.toString();
}
}