1 16 package org.jahia.services.search; 17 18 import org.apache.lucene.analysis.Analyzer; 19 import org.apache.lucene.document.Field; 20 import org.apache.lucene.index.IndexReader; 21 import org.apache.lucene.index.Term; 22 import org.apache.lucene.queryParser.QueryParser; 23 import org.apache.lucene.document.Document; 24 import org.apache.lucene.search.*; 25 import org.jahia.data.search.JahiaSearchResult; 26 import org.jahia.exceptions.JahiaException; 27 import org.jahia.params.ParamBean; 28 import org.jahia.registries.ServicesRegistry; 29 import org.jahia.services.fields.ContentField; 30 import org.jahia.services.search.analyzer.SearchQueryParser; 31 import org.jahia.services.version.EntryLoadRequest; 32 33 import java.util.*; 34 import java.io.IOException ; 35 36 37 42 43 class SearchEngine { 44 45 51 private class ClosableIndexSearcher extends IndexSearcher 52 { 53 private IndexReader indexReader; 54 55 60 protected ClosableIndexSearcher(IndexReader reader) 61 { 62 super(reader); 63 indexReader = reader; 64 } 65 66 71 public void close() throws IOException 72 { 73 indexReader.close(); 74 } 75 } 76 77 private static org.apache.log4j.Logger logger = 78 org.apache.log4j.Logger.getLogger (SearchEngine.class); 79 80 private Analyzer analyzer; 81 82 private boolean doAutoAppendWildcards; 83 84 90 public SearchEngine (Analyzer theAnalyzer, IndexReader reader) { 91 analyzer = theAnalyzer; 92 doAutoAppendWildcards = false; 93 } 94 95 105 public JahiaSearchResult doPageSearch (JahiaSearcher jSearcher, 106 ParamBean jParams) 107 throws JahiaException { 108 logger.info ("Started"); 109 110 JahiaSearchResultHandlerImpl jahiaSearchResultHandler 111 = new JahiaSearchResultHandlerImpl(); 112 113 JahiaSearchResult result = new JahiaSearchResult (new JahiaSearchResultHandlerImpl()); 114 115 MultiSearcher multiSearcher = null; 116 117 if ( jSearcher == null || jSearcher.getQuery () == null) 118 return result; 119 120 try { 121 122 QueryParser parser = new SearchQueryParser(JahiaSearchConstant.FIELD_TEXT, 123 analyzer, doAutoAppendWildcards); 124 parser.setOperator(QueryParser.DEFAULT_OPERATOR_AND); 125 126 BooleanQuery resultQuery = new BooleanQuery(); 127 resultQuery.add(parser.parse(jSearcher.getQuery()), true, false); 128 appendLanguageAndStateQuery(resultQuery, jSearcher, jParams); 129 130 int[] siteIds = jSearcher.getSiteIds(); 131 ArrayList sites = new ArrayList(siteIds.length); 132 for ( int i=0; i<siteIds.length; i++ ){ 133 sites.add(new Integer (siteIds[i])); 134 } 135 136 multiSearcher = this.getSearcher(sites); 137 138 Hits hits = null; 140 if ( multiSearcher != null ){ 141 hits = multiSearcher.search(resultQuery); 142 } 143 144 List parsedObjects = getParsedObjects(hits); 145 if ( parsedObjects == null ){ 146 parsedObjects = Collections.EMPTY_LIST; 147 } 148 result = jahiaSearchResultHandler.buildResult(parsedObjects, jParams); 149 150 } catch (Throwable t) { 151 logger.error (t); 152 } finally { 153 closeSearcher(multiSearcher); 154 } 155 return result; 156 } 157 158 167 public JahiaSearchResult doContainerSearch (JahiaSearcher jSearcher, 168 ParamBean jParams) 169 throws JahiaException { 170 logger.debug ("Started"); 171 172 JahiaSearchResultHandlerImpl jahiaSearchResultHandler 173 = new JahiaSearchResultHandlerImpl(); 174 175 JahiaSearchResult result = new JahiaSearchResult (jahiaSearchResultHandler); 176 177 if (jSearcher == null || jSearcher.getQuery () == null) 178 return result; 179 180 MultiSearcher multiSearcher = null; 181 182 try { 183 184 ContainerSearcher cSearcher = (ContainerSearcher) jSearcher; 185 186 ServicesRegistry sReg = ServicesRegistry.getInstance (); 187 188 QueryParser parser = new SearchQueryParser(JahiaSearchConstant.FIELD_TEXT, 190 analyzer, doAutoAppendWildcards); 191 parser.setOperator(QueryParser.DEFAULT_OPERATOR_AND); 192 193 BooleanQuery resultQuery = new BooleanQuery(); 194 resultQuery.add(parser.parse(cSearcher.getQuery()), true, false); 195 appendLanguageAndStateQuery(resultQuery, jSearcher, jParams); 196 197 if (!cSearcher.isSiteModeSearching ()) { 198 List ctnids = sReg.getJahiaContainersService ().getctnidsInList ( 201 cSearcher.getCtnListID (), jParams.getEntryLoadRequest ()); 202 if (ctnids.size () == 0) 203 return result; 204 205 BooleanQuery containerQuery = new BooleanQuery(); 206 for (Iterator iter = ctnids.iterator(); iter.hasNext();) 207 { 208 containerQuery.add(new TermQuery(new Term( 209 JahiaSearchConstant.FIELD_CTNID, iter.next().toString())), false, 210 false); 211 } 212 213 resultQuery.add(containerQuery, true, false); 214 } else { 215 216 if (cSearcher.getSiteId () != -1) { 217 resultQuery.add(new TermQuery(new Term( 218 JahiaSearchConstant.FIELD_JAHIAID, String.valueOf(cSearcher 219 .getSiteId()))), true, false); 220 } 221 222 if (cSearcher.getContainerDefinitionName () != null 223 && !"".equals (cSearcher.getContainerDefinitionName().trim ())) { 224 resultQuery.add(new TermQuery(new Term( 225 JahiaSearchConstant.CONTAINER_DEFINITION_NAME, cSearcher 226 .getContainerDefinitionName().toLowerCase())), true, false); 227 } 228 } 229 230 if (logger.isDebugEnabled()) 231 { 232 logger.debug ("Query is: " + resultQuery.toString()); 233 } 234 235 ArrayList sites = new ArrayList(cSearcher.isSiteModeSearching() 236 ? cSearcher.getSiteIds().length : 1); 237 if ( cSearcher.isSiteModeSearching() ){ 238 int[] siteIds = cSearcher.getSiteIds(); 239 for ( int i=0; i<siteIds.length; i++ ){ 240 sites.add(new Integer (siteIds[i])); 241 } 242 } else { 243 sites.add(new Integer (jParams.getJahiaID())); 244 } 245 246 multiSearcher = this.getSearcher(sites); 247 248 Hits hits = null; 250 if ( multiSearcher != null ){ 251 hits = multiSearcher.search(resultQuery); 252 } 253 254 if (hits == null || hits.length () == 0) 255 return result; 256 257 logger.debug ("lucene result : " + hits.length ()); 258 259 Vector parsedObjects = getParsedObjects(hits); 260 if ( parsedObjects == null ){ 261 parsedObjects = new Vector(); 262 } 263 result = jahiaSearchResultHandler.buildContainerSearchResult(parsedObjects, true, jParams); 264 265 logger.debug ("jahia result : " + result.getHitCount ()); 266 267 } catch (Throwable t) { 268 logger.error (t); 269 } finally { 270 closeSearcher(multiSearcher); 271 } 272 return result; 273 } 274 275 private MultiSearcher getSearcher(ArrayList sites) throws IOException , JahiaException { 276 277 JahiaSearchService sServ = ServicesRegistry.getInstance().getJahiaSearchService(); 278 Searchable searcher = null; 279 RAMIndexer ramIndexer = sServ.getRAMIndexer(); 280 ArrayList searchables = new ArrayList(ramIndexer != null ? sites.size() * 2 281 : sites.size()); 282 Integer I = null; 283 IndexReader reader = null; 284 for ( int i=0; i<sites.size(); i++ ){ 285 I = (Integer )sites.get(i); 286 reader = sServ.getIndexReader(I.intValue()); 287 if (reader != null) 288 { 289 searcher = new ClosableIndexSearcher(reader); 290 searchables.add(searcher); 291 } 292 if ( ramIndexer != null ){ 293 searcher = ramIndexer.getSearcher(I.intValue()); 294 if ( searcher != null ){ 295 searchables.add(searcher); 296 } 297 } 298 } 299 300 if (searchables.size() == 0) 301 return null; 302 303 Searchable[] searchablesAr = new Searchable[searchables.size()]; 304 searchables.toArray(searchablesAr); 305 return new MultiSearcher(searchablesAr); 306 } 307 308 315 private void appendLanguageAndStateQuery(BooleanQuery query, JahiaSearcher jSearcher, ParamBean jParams) { 316 317 EntryLoadRequest elr = jParams.getEntryLoadRequest(); 318 if (elr.isCurrent()) 319 { 320 query.add(new TermQuery(new Term( 321 JahiaSearchConstant.FIELD_WORKFLOW_STATE, String 322 .valueOf(EntryLoadRequest.ACTIVE_WORKFLOW_STATE))), true, false); 323 } 324 325 if (!jSearcher.getLanguageCodes().isEmpty()) 326 { 327 BooleanQuery languageQuery = new BooleanQuery(); 329 languageQuery.add( 330 new TermQuery(new Term(JahiaSearchConstant.FIELD_LANGUAGE_CODE, 331 ContentField.SHARED_LANGUAGE)), false, false); 332 333 Set lngSet = new HashSet(); 334 lngSet.add(ContentField.SHARED_LANGUAGE); 335 336 for (Iterator iter = jSearcher.getLanguageCodes().iterator(); iter 337 .hasNext();) 338 { 339 String lng = (String )iter.next(); 340 if (!lngSet.contains(lng)) 341 { 342 languageQuery.add(new TermQuery(new Term( 343 JahiaSearchConstant.FIELD_LANGUAGE_CODE, lng)), false, false); 344 lngSet.add(lng); 345 } 346 } 347 348 query.add(languageQuery, true, false); 349 } 350 } 351 352 357 private Vector getParsedObjects(Hits hits) throws Exception { 358 Vector parsedObjects = new Vector(); 359 if ( hits == null || hits.length()==0 ){ 360 return parsedObjects; 361 } 362 int size = hits.length(); 363 for ( int i=0; i<size; i++ ){ 364 ParsedObjectImpl parsedObject = new ParsedObjectImpl(); 365 Hashtable map = new Hashtable(); 366 Document doc = hits.doc(i); 367 Enumeration fields = doc.fields(); 368 Field field = null; 369 String name = null; 370 while ( fields.hasMoreElements() ){ 371 field = (Field)fields.nextElement(); 372 name = field.name(); 373 if ( !map.contains(name) ){ 374 map.put(name, doc.getValues(name)); 375 } 376 } 377 parsedObject.setFields(map); 378 parsedObject.setScore(hits.score(i)); 379 parsedObjects.add(parsedObject); 380 } 381 return parsedObjects; 382 } 383 384 private void closeSearcher(MultiSearcher searcher) 385 { 386 if (searcher != null) 387 { 388 try 389 { 390 searcher.close(); 391 } 392 catch (IOException ex) 393 { 394 logger.debug("Error closing searcher", ex); 395 } 396 } 397 } 398 } 399 | Popular Tags |