1 23 package org.ofbiz.product.product; 24 25 import java.util.HashMap ; 26 import java.util.HashSet ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.Map ; 30 import java.util.Set ; 31 import java.util.StringTokenizer ; 32 import java.util.TreeSet ; 33 34 import org.ofbiz.base.util.Debug; 35 import org.ofbiz.base.util.UtilMisc; 36 import org.ofbiz.base.util.UtilProperties; 37 import org.ofbiz.base.util.UtilValidate; 38 import org.ofbiz.entity.GenericDelegator; 39 import org.ofbiz.entity.GenericEntityException; 40 import org.ofbiz.entity.GenericValue; 41 42 50 public class KeywordSearch { 51 52 public static final String module = KeywordSearch.class.getName(); 53 54 public static Set thesaurusRelsToInclude = new HashSet (); 55 public static Set thesaurusRelsForReplace = new HashSet (); 56 57 static { 58 thesaurusRelsToInclude.add("KWTR_UF"); 59 thesaurusRelsToInclude.add("KWTR_USE"); 60 thesaurusRelsToInclude.add("KWTR_CS"); 61 thesaurusRelsToInclude.add("KWTR_NT"); 62 thesaurusRelsToInclude.add("KWTR_BT"); 63 thesaurusRelsToInclude.add("KWTR_RT"); 64 65 thesaurusRelsForReplace.add("KWTR_USE"); 66 thesaurusRelsForReplace.add("KWTR_CS"); 67 } 68 69 public static String getSeparators() { 70 String seps = UtilProperties.getPropertyValue("prodsearch", "index.keyword.separators", ";: ,.!?\t\"\'\r\n\\/()[]{}*%<>-+_"); 72 return seps; 73 } 74 75 public static String getStopWordBagOr() { 76 return UtilProperties.getPropertyValue("prodsearch", "stop.word.bag.or"); 77 } 78 public static String getStopWordBagAnd() { 79 return UtilProperties.getPropertyValue("prodsearch", "stop.word.bag.and"); 80 } 81 82 public static boolean getRemoveStems() { 83 String removeStemsStr = UtilProperties.getPropertyValue("prodsearch", "remove.stems"); 84 return "true".equals(removeStemsStr); 85 } 86 public static Set getStemSet() { 87 String stemBag = UtilProperties.getPropertyValue("prodsearch", "stem.bag"); 88 Set stemSet = new TreeSet (); 89 if (UtilValidate.isNotEmpty(stemBag)) { 90 String curToken; 91 StringTokenizer tokenizer = new StringTokenizer (stemBag, ": "); 92 while (tokenizer.hasMoreTokens()) { 93 curToken = tokenizer.nextToken(); 94 stemSet.add(curToken); 95 } 96 } 97 return stemSet; 98 } 99 100 public static void processForKeywords(String str, Map keywords, boolean forSearch, boolean anyPrefix, boolean anySuffix, boolean isAnd) { 101 String separators = getSeparators(); 102 String stopWordBagOr = getStopWordBagOr(); 103 String stopWordBagAnd = getStopWordBagAnd(); 104 105 boolean removeStems = getRemoveStems(); 106 Set stemSet = getStemSet(); 107 108 processForKeywords(str, keywords, separators, stopWordBagAnd, stopWordBagOr, removeStems, stemSet, forSearch, anyPrefix, anySuffix, isAnd); 109 } 110 111 public static void processKeywordsForIndex(String str, Map keywords, String separators, String stopWordBagAnd, String stopWordBagOr, boolean removeStems, Set stemSet) { 112 processForKeywords(str, keywords, separators, stopWordBagAnd, stopWordBagOr, removeStems, stemSet, false, false, false, false); 113 } 114 115 public static void processForKeywords(String str, Map keywords, String separators, String stopWordBagAnd, String stopWordBagOr, boolean removeStems, Set stemSet, boolean forSearch, boolean anyPrefix, boolean anySuffix, boolean isAnd) { 116 Set keywordSet = makeKeywordSet(str, separators, forSearch); 117 fixupKeywordSet(keywordSet, keywords, stopWordBagAnd, stopWordBagOr, removeStems, stemSet, forSearch, anyPrefix, anySuffix, isAnd); 118 } 119 120 public static void fixupKeywordSet(Set keywordSet, Map keywords, String stopWordBagAnd, String stopWordBagOr, boolean removeStems, Set stemSet, boolean forSearch, boolean anyPrefix, boolean anySuffix, boolean isAnd) { 121 if (keywordSet == null) { 122 return; 123 } 124 125 Iterator keywordIter = keywordSet.iterator(); 126 while (keywordIter.hasNext()) { 127 String token = (String ) keywordIter.next(); 128 129 131 String colonToken = ":" + token + ":"; 133 if (forSearch) { 134 if ((isAnd && stopWordBagAnd.indexOf(colonToken) >= 0) || (!isAnd && stopWordBagOr.indexOf(colonToken) >= 0)) { 135 continue; 136 } 137 } else { 138 if (stopWordBagOr.indexOf(colonToken) >= 0 && stopWordBagAnd.indexOf(colonToken) >= 0) { 139 continue; 140 } 141 } 142 143 if (removeStems) { 145 Iterator stemIter = stemSet.iterator(); 146 while (stemIter.hasNext()) { 147 String stem = (String ) stemIter.next(); 148 if (token.endsWith(stem)) { 149 token = token.substring(0, token.length() - stem.length()); 150 } 151 } 152 } 153 154 if (token.length() == 0) { 156 continue; 157 } 158 159 if (token.length() == 1 && Character.isLetter(token.charAt(0))) { 161 continue; 162 } 163 164 if (forSearch) { 165 StringBuffer strSb = new StringBuffer (); 166 if (anyPrefix) strSb.append('%'); 167 strSb.append(token); 168 if (anySuffix) strSb.append('%'); 169 int dblPercIdx = -1; 171 while ((dblPercIdx = strSb.indexOf("%%")) >= 0) { 172 strSb.replace(dblPercIdx, dblPercIdx+2, "%"); 174 } 176 token = strSb.toString(); 177 } 178 179 Long curWeight = (Long ) keywords.get(token); 181 if (curWeight == null) { 182 keywords.put(token, new Long (1)); 183 } else { 184 keywords.put(token, new Long (curWeight.longValue() + 1)); 185 } 186 } 187 } 188 189 public static Set makeKeywordSet(String str, String separators, boolean forSearch) { 190 if (separators == null) separators = getSeparators(); 191 192 Set keywords = new TreeSet (); 193 if (str.length() > 0) { 194 if (forSearch) { 195 StringBuffer sb = new StringBuffer (separators); 197 if (sb.indexOf("%") >= 0) sb.deleteCharAt(sb.indexOf("%")); 198 if (sb.indexOf("_") >= 0) sb.deleteCharAt(sb.indexOf("_")); 199 if (sb.indexOf("*") >= 0) sb.deleteCharAt(sb.indexOf("*")); 200 if (sb.indexOf("?") >= 0) sb.deleteCharAt(sb.indexOf("?")); 201 separators = sb.toString(); 202 } 203 204 StringTokenizer tokener = new StringTokenizer (str, separators, false); 205 while (tokener.hasMoreTokens()) { 206 String token = tokener.nextToken().toLowerCase(); 208 209 if (forSearch) { 210 token = token.replace('*', '%'); 212 token = token.replace('?', '_'); 213 } 214 215 keywords.add(token); 216 } 217 } 218 return keywords; 219 } 220 221 public static Set fixKeywordsForSearch(Set keywordSet, boolean anyPrefix, boolean anySuffix, boolean removeStems, boolean isAnd) { 222 Map keywords = new HashMap (); 223 fixupKeywordSet(keywordSet, keywords, getStopWordBagAnd(), getStopWordBagOr(), removeStems, getStemSet(), true, anyPrefix, anySuffix, isAnd); 224 return keywords.keySet(); 225 } 226 227 public static boolean expandKeywordForSearch(String enteredKeyword, Set addToSet, GenericDelegator delegator) { 228 boolean replaceEnteredKeyword = false; 229 230 try { 231 List thesaurusList = delegator.findByAndCache("KeywordThesaurus", UtilMisc.toMap("enteredKeyword", enteredKeyword)); 232 Iterator thesaurusIter = thesaurusList.iterator(); 233 while (thesaurusIter.hasNext()) { 234 GenericValue keywordThesaurus = (GenericValue) thesaurusIter.next(); 235 String relationshipEnumId = (String ) keywordThesaurus.get("relationshipEnumId"); 236 if (thesaurusRelsToInclude.contains(relationshipEnumId)) { 237 addToSet.addAll(makeKeywordSet(keywordThesaurus.getString("alternateKeyword"), null, true)); 238 if (thesaurusRelsForReplace.contains(relationshipEnumId)) { 239 replaceEnteredKeyword = true; 240 } 241 } 242 } 243 } catch (GenericEntityException e) { 244 Debug.logError(e, "Error expanding entered keyword", module); 245 } 246 247 Debug.logInfo("Expanded keyword [" + enteredKeyword + "], got set: " + addToSet, module); 248 return replaceEnteredKeyword; 249 } 250 251 public static void induceKeywords(GenericValue product) throws GenericEntityException { 252 if (product == null) return; 253 KeywordIndex.indexKeywords(product, false); 254 } 255 256 public static void induceKeywords(GenericValue product, boolean doAll) throws GenericEntityException { 257 if (product == null) return; 258 KeywordIndex.indexKeywords(product, doAll); 259 } 260 } 261 | Popular Tags |