001
014
015 package com.liferay.portal.kernel.search.util;
016
017 import com.liferay.portal.kernel.util.ArrayUtil;
018 import com.liferay.portal.kernel.util.StringBundler;
019 import com.liferay.portal.kernel.util.StringPool;
020 import com.liferay.portal.kernel.util.Validator;
021
022 import java.util.StringTokenizer;
023 import java.util.regex.Matcher;
024 import java.util.regex.Pattern;
025
026
029 public class SearchUtil {
030
031 public static final String[] HIGHLIGHTS =
032 {"<span class=\"highlight\">", "</span>"};
033
034 public static String highlight(String s, String[] queryTerms) {
035 return highlight(s, queryTerms, HIGHLIGHTS[0], HIGHLIGHTS[1]);
036 }
037
038 public static String highlight(
039 String s, String[] queryTerms, String highlight1, String highlight2) {
040
041 if (Validator.isNull(s) || ArrayUtil.isEmpty(queryTerms)) {
042 return s;
043 }
044
045 if (queryTerms.length == 0) {
046 return StringPool.BLANK;
047 }
048
049 StringBundler sb = new StringBundler(2 * queryTerms.length - 1);
050
051 for (int i = 0; i < queryTerms.length; i++) {
052 sb.append(Pattern.quote(queryTerms[i].trim()));
053
054 if ((i + 1) < queryTerms.length) {
055 sb.append(StringPool.PIPE);
056 }
057 }
058
059 int flags = Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
060
061 Pattern pattern = Pattern.compile(sb.toString(), flags);
062
063 return _highlight(s, pattern, highlight1, highlight2);
064 }
065
066 private static String _highlight(
067 String s, Pattern pattern, String highlight1, String highlight2) {
068
069 StringTokenizer st = new StringTokenizer(s);
070
071 if (st.countTokens() == 0) {
072 return StringPool.BLANK;
073 }
074
075 StringBundler sb = new StringBundler(2 * st.countTokens() - 1);
076
077 while (st.hasMoreTokens()) {
078 String token = st.nextToken();
079
080 Matcher matcher = pattern.matcher(token);
081
082 if (matcher.find()) {
083 StringBuffer hightlighted = new StringBuffer();
084
085 while (true) {
086 matcher.appendReplacement(
087 hightlighted,
088 highlight1 + matcher.group() + highlight2);
089
090 if (!matcher.find()) {
091 break;
092 }
093 }
094
095 matcher.appendTail(hightlighted);
096
097 sb.append(hightlighted);
098 }
099 else {
100 sb.append(token);
101 }
102
103 if (st.hasMoreTokens()) {
104 sb.append(StringPool.SPACE);
105 }
106 }
107
108 return sb.toString();
109 }
110
111 }