1 package org.jahia.services.search; 2 3 import org.jahia.exceptions.JahiaException; 4 import org.jahia.data.search.JahiaSearchResult; 5 import org.jahia.data.search.JahiaSearchHit; 6 import org.jahia.params.ParamBean; 7 8 import java.util.*; 9 10 13 public class ChainedJahiaSearcher extends JahiaSearcher 14 { 15 16 private static org.apache.log4j.Logger logger = 17 org.apache.log4j.Logger.getLogger (ChainedJahiaSearcher.class); 18 19 private static String CHAINED_JAHIA_SEARCHER = "chainedJahiaSearcher"; 20 21 private String name = CHAINED_JAHIA_SEARCHER; 22 23 26 public static final int OR = 0; 27 28 31 public static final int AND = 1; 32 33 36 public static final int ANDNOT = 2; 37 38 41 public static final int XOR = 3; 42 43 47 public static int DEFAULT = OR; 48 49 50 private JahiaSearcher[] chain = null; 51 52 private int[] logicArray; 53 54 private int logic = -1; 55 56 60 public ChainedJahiaSearcher(JahiaSearcher[] chain) 61 { 62 this.chain = chain; 63 } 64 65 70 public ChainedJahiaSearcher(JahiaSearcher[] chain, int[] logicArray) 71 { 72 this.chain = chain; 73 this.logicArray = logicArray; 74 } 75 76 81 public ChainedJahiaSearcher(JahiaSearcher[] chain, int logic) 82 { 83 this.chain = chain; 84 this.logic = logic; 85 } 86 87 88 94 public int[] getSiteIds (){ 95 int[] siteIds = new int[]{}; 96 if ( this.chain.length>0 ){ 97 siteIds = ((JahiaSearcher)this.chain[0]).getSiteIds(); 98 } 99 return siteIds; 100 } 101 102 public String getName (){ 103 return this.name; 104 } 105 106 116 public JahiaSearchResult search (String query, ParamBean jParams) 117 throws JahiaException{ 118 119 setQuery (query); 121 122 JahiaSearchResult result = this.bits(jParams); 123 124 this.setResult(result); 125 return (JahiaSearchResult)this.getResult(); 126 } 127 128 public JahiaSearcher[] getChain() { 129 return chain; 130 } 131 132 public void setChain(JahiaSearcher[] chain) { 133 this.chain = chain; 134 } 135 136 137 142 public ArrayList getLanguageCodes (){ 143 ArrayList langCodes = new ArrayList(); 144 if ( this.chain.length>0 ){ 145 langCodes = ((JahiaSearcher)this.chain[0]).getLanguageCodes(); 146 } 147 return langCodes; 148 } 149 150 public String getQuery() { 151 if ( chain == null ){ 152 return ""; 153 } 154 StringBuffer buff = new StringBuffer (); 155 JahiaSearcher searcher = null; 156 String val = ""; 157 for ( int i=0; i<chain.length; i++ ){ 158 searcher = (JahiaSearcher)chain[i]; 159 val = searcher.getQuery(); 160 if ( val != null ){ 161 if (i > 0) { 162 int logop = (this.logic != -1) ? this.logic : 163 this.logicArray[i-1]; 164 switch (logop) { 165 case OR: 166 buff.append(" UNION "); 167 break; 168 case AND: 169 buff.append(" INTERSECT "); 170 break; 171 case XOR: 172 buff.append(" XOR "); break; 174 case ANDNOT: 175 buff.append(" ANDNOT "); break; 177 default: 178 buff.append(" DEFAULT_OPERATOR "); break; 180 } 181 } 182 183 buff.append(val); 184 } 185 } 186 return buff.toString(); 187 } 188 189 private JahiaSearchResult bits(ParamBean jParams) throws JahiaException 190 { 191 if (logic != -1) 192 return bitsFromLogic(logic, jParams); 193 else if (logicArray != null) 194 return bits(logicArray, jParams); 195 else 196 return bitsFromLogic(DEFAULT, jParams); 197 } 198 199 204 private JahiaSearchResult bitsFromLogic(int logic, ParamBean jParams) 205 throws JahiaException { 206 JahiaSearchResult result; 207 int i = 0; 208 209 214 215 if (logic == AND) 216 { 217 result = (JahiaSearchResult) chain[i].search(chain[i].getQuery(),jParams); 218 ++i; 219 } 220 else 221 { 222 result = new JahiaSearchResult(new JahiaSearchResultHandlerImpl()); 223 } 224 225 HashMap hitsMap = new HashMap(); 226 JahiaSearchHit hit = null; 227 Vector hits = result.results(); 228 Vector v = null; 229 int size = hits.size(); 230 for ( i=0; i<size; i++ ){ 231 hit = (JahiaSearchHit)hits.get(i); 232 v = (Vector) hitsMap.get(new Integer (hit.id)); 233 if ( v == null ){ 234 v = new Vector(); 235 hitsMap.put(new Integer (hit.id),v); 236 } 237 v.add(hit); 238 } 239 240 i=0; 241 for (; i < chain.length; i++) 242 { 243 doChain(hitsMap, logic, chain[i], jParams); 244 } 245 246 return buildResultFromHitsMap(hitsMap); 247 } 248 249 254 private JahiaSearchResult bits(int[] logic, ParamBean jParams) 255 throws JahiaException { 256 if (logic.length < chain.length-1) 257 throw new IllegalArgumentException ("Invalid number of elements in logic array"); 258 259 JahiaSearchResult result = chain[0].search(chain[0].getQuery(),jParams); 260 261 HashMap hitsMap = new HashMap(); 262 JahiaSearchHit hit = null; 263 Vector hits = result.results(); 264 Vector v = null; 265 int size = hits.size(); 266 for ( int i=0; i<size; i++ ){ 267 hit = (JahiaSearchHit)hits.get(i); 268 v = (Vector) hitsMap.get(new Integer (hit.id)); 269 if ( v == null ){ 270 v = new Vector(); 271 hitsMap.put(new Integer (hit.id),v); 272 } 273 v.add(hit); 274 } 275 276 for (int i=1; i < chain.length; i++) 277 { 278 doChain(hitsMap, logic[i-1], chain[i], jParams); 279 } 280 return buildResultFromHitsMap(hitsMap); 281 } 282 283 private JahiaSearchResult buildResultFromHitsMap(HashMap hitsMap){ 284 JahiaSearchResult result = new JahiaSearchResult(new JahiaSearchResultHandlerImpl()); 285 Iterator iterator = hitsMap.values().iterator(); 286 Vector v = null; 287 Vector parsedObjects = new Vector(); 288 JahiaSearchHit hit = null; 289 JahiaSearchHit hit2 = null; 290 while ( iterator.hasNext() ){ 291 v = (Vector)iterator.next(); 292 hit = null; 293 for ( int i=0; i<v.size(); i++ ){ 294 hit2 = (JahiaSearchHit)v.get(i); 295 if ( hit == null || hit.getScore()<hit2.getScore() ){ 296 hit = hit2; 297 } 298 } 299 parsedObjects.add(hit.getParsedObject()); 300 result.addHit(hit); 301 } 302 result.setParsedObjects(parsedObjects); 303 result.pages = result.results(); 304 result.pagecount = result.getHitCount(); 305 306 return result; 307 } 308 309 private void doChain(HashMap hitsMap, int logic, JahiaSearcher searcher, 310 ParamBean jParams) throws JahiaException 311 { 312 switch (logic) 313 { 314 case OR: 315 mergeResults(hitsMap, logic, searcher, jParams); 316 break; 317 case AND: 318 mergeResults(hitsMap, logic, searcher, jParams); 319 break; 320 case ANDNOT: 321 mergeResults(hitsMap, logic, searcher, jParams); 322 break; 323 case XOR: 324 mergeResults(hitsMap, logic, searcher, jParams); 325 break; 326 default: 327 doChain(hitsMap, DEFAULT, searcher, jParams); 328 break; 329 } 330 } 331 332 private void mergeResults(HashMap hitsMap, int logic, 333 JahiaSearcher searcher, ParamBean jParams) 334 throws JahiaException { 335 336 JahiaSearchResult result = new JahiaSearchResult(new JahiaSearchResultHandlerImpl()); 337 338 JahiaSearchResult result2 = searcher.search(searcher.getQuery(),jParams); 339 Vector hits2 = null; 340 JahiaSearchHit newHit = null; 341 int size = 0; 342 343 hits2 = result2.results(); 344 Vector v = null; 345 size = hits2.size(); 346 347 for( int i=0; i<size; i++ ){ 348 newHit = (JahiaSearchHit)hits2.get(i); 349 v = (Vector)hitsMap.get(new Integer (newHit.id)); 350 switch (logic) 351 { 352 case OR: 353 if ( v == null ){ 354 v = new Vector(); 355 hitsMap.put(new Integer (newHit.id),v); 356 } 357 v.add(newHit); 358 break; 359 case AND: 360 if ( v != null ){ 361 v.add(newHit); 362 } 363 break; 364 case ANDNOT: 365 newHit = (JahiaSearchHit)hits2.get(i); 366 hitsMap.remove(new Integer (newHit.id)); 367 break; 368 case XOR: 369 newHit = (JahiaSearchHit)hits2.get(i); 370 if ( hitsMap.containsKey(new Integer (newHit.id)) ){ 371 hitsMap.remove(new Integer (newHit.id)); 372 } 373 break; 374 } 375 } 376 377 if ( logic == AND ){ 378 Iterator iterator = hitsMap.keySet().iterator(); 379 Integer I = null; 380 v = new Vector(); 381 while ( iterator.hasNext() ){ 382 I = (Integer )iterator.next(); 383 if ( !result2.bits().get(I.intValue()) ){ 384 v.add(I); 385 } 386 } 387 Enumeration col = v.elements(); 388 while ( col.hasMoreElements() ){ 389 I = (Integer )col.nextElement(); 390 hitsMap.remove(I); 391 } 392 } 393 } 394 395 public String toString() 396 { 397 StringBuffer sb = new StringBuffer (); 398 sb.append("ChainedJahiaSearcher: ["); 399 for (int i = 0; i < chain.length; i++) 400 { 401 if (i>0) { 402 int logop = (this.logic != -1) ? this.logic : this.logicArray[i-1] ; 403 switch (logop) { 404 case OR: 405 sb.append(" OR "); 406 break; 407 case AND: 408 sb.append(" AND "); 409 break; 410 case XOR: 411 sb.append(" XOR "); 412 break; 413 case ANDNOT: 414 sb.append(" XOR "); 415 break; 416 default: 417 sb.append(" OR "); 418 break; 419 } 420 } 421 sb.append(chain[i]); 422 sb.append(' '); 423 } 424 sb.append(']'); 425 return sb.toString(); 426 } 427 428 429 } 430 | Popular Tags |