1 6 package org.roller.business; 7 8 import java.io.File ; 9 import java.io.IOException ; 10 11 import org.apache.commons.logging.Log; 12 import org.apache.commons.logging.LogFactory; 13 import org.apache.lucene.analysis.Analyzer; 14 import org.apache.lucene.analysis.standard.StandardAnalyzer; 15 import org.apache.lucene.index.IndexReader; 16 import org.apache.lucene.index.IndexWriter; 17 import org.apache.lucene.store.Directory; 18 import org.apache.lucene.store.FSDirectory; 19 import org.apache.lucene.store.RAMDirectory; 20 import org.roller.RollerException; 21 import org.roller.business.search.operations.AddEntryOperation; 22 import org.roller.business.search.operations.IndexOperation; 23 import org.roller.business.search.operations.ReIndexEntryOperation; 24 import org.roller.business.search.operations.RebuildUserIndexOperation; 25 import org.roller.business.search.operations.RemoveEntryOperation; 26 import org.roller.business.search.operations.RemoveUserIndexOperation; 27 import org.roller.business.search.operations.WriteToIndexOperation; 28 import org.roller.model.IndexManager; 29 import org.roller.pojos.UserData; 30 import org.roller.pojos.WeblogEntryData; 31 32 import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock; 33 import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock; 34 import org.roller.config.RollerConfig; 35 import org.roller.model.RollerFactory; 36 import org.roller.util.StringUtils; 37 38 44 public class IndexManagerImpl implements IndexManager 45 { 46 49 private IndexReader reader; 50 51 static Log mLogger = LogFactory.getFactory().getInstance( 52 IndexManagerImpl.class); 53 54 57 private boolean searchEnabled = true; 58 59 File indexConsistencyMarker; 60 61 private boolean useRAMIndex = false; 62 63 private RAMDirectory fRAMindex; 64 65 private String indexDir = null; 66 67 private boolean inconsistentAtStartup = false; 68 69 private ReadWriteLock rwl = new WriterPreferenceReadWriteLock(); 70 71 74 83 public IndexManagerImpl() 84 { 85 String enabled = RollerConfig.getProperty("search.enabled"); 87 if("false".equalsIgnoreCase(enabled)) 88 this.searchEnabled = false; 89 90 String indexDir = RollerConfig.getProperty("search.index.dir"); 92 if (indexDir.indexOf("${user.home}") != -1) 93 { 94 indexDir = StringUtils.replace( 95 indexDir, "${user.home}", 96 System.getProperty("user.home")); 97 } 98 99 this.indexDir = indexDir.replace('/', File.separatorChar); 100 101 mLogger.info("search enabled: " + this.searchEnabled); 103 mLogger.info("index dir: " + this.indexDir); 104 105 String test = indexDir + File.separator + ".index-inconsistent"; 106 indexConsistencyMarker = new File (test); 107 108 if (this.searchEnabled) 110 { 111 112 if (indexConsistencyMarker.exists()) 118 { 119 getFSDirectory(true); 120 inconsistentAtStartup = true; 121 } 122 else 123 { 124 try 125 { 126 File makeIndexDir = new File (indexDir); 127 if (!makeIndexDir.exists()) 128 { 129 makeIndexDir.mkdirs(); 130 inconsistentAtStartup = true; 131 } 132 indexConsistencyMarker.createNewFile(); 133 } 134 catch (IOException e) 135 { 136 mLogger.error(e); 137 } 138 } 139 140 if (indexExists()) 141 { 142 if (useRAMIndex) 143 { 144 Directory filesystem = getFSDirectory(false); 145 146 try 147 { 148 fRAMindex = new RAMDirectory(filesystem); 149 } 150 catch (IOException e) 151 { 152 mLogger.error("Error creating in-memory index", e); 153 } 154 } 155 } 156 else 157 { 158 if (useRAMIndex) 159 { 160 fRAMindex = new RAMDirectory(); 161 createIndex(fRAMindex); 162 } 163 else 164 { 165 createIndex(getFSDirectory(true)); 166 } 167 } 168 169 if (isInconsistentAtStartup()) 170 { 171 mLogger.info( 172 "Index was inconsistent. Rebuilding index in the background..."); 173 try 174 { 175 rebuildUserIndex(); 176 } 177 catch (RollerException e) 178 { 179 mLogger.error("ERROR: scheduling re-index operation"); 180 } 181 } 182 } 183 } 184 185 188 public void rebuildUserIndex() throws RollerException 189 { 190 scheduleIndexOperation( 191 new RebuildUserIndexOperation(this, null)); 192 } 193 194 public void removeUserIndex(UserData user) throws RollerException 195 { 196 scheduleIndexOperation( 197 new RemoveUserIndexOperation(this, user)); 198 } 199 200 public void addEntryIndexOperation(WeblogEntryData entry) throws RollerException 201 { 202 AddEntryOperation addEntry = new AddEntryOperation(this, entry); 203 scheduleIndexOperation(addEntry); 204 } 205 206 public void addEntryReIndexOperation(WeblogEntryData entry) throws RollerException 207 { 208 ReIndexEntryOperation reindex = new ReIndexEntryOperation(this, entry); 209 scheduleIndexOperation(reindex); 210 } 211 212 public void removeEntryIndexOperation(WeblogEntryData entry) throws RollerException 213 { 214 RemoveEntryOperation removeOp = new RemoveEntryOperation(this, entry); 215 executeIndexOperationNow(removeOp); 216 } 217 218 public ReadWriteLock getReadWriteLock() 219 { 220 return rwl; 221 } 222 223 public boolean isInconsistentAtStartup() 224 { 225 return inconsistentAtStartup; 226 } 227 228 233 public static final Analyzer getAnalyzer() 234 { 235 return new StandardAnalyzer(); 236 } 237 238 private void scheduleIndexOperation(final IndexOperation op) 239 { 240 try 241 { 242 if(this.searchEnabled) { 244 mLogger.debug("Starting scheduled index operation: "+op.getClass().getName()); 245 RollerFactory.getRoller().getThreadManager().executeInBackground(op); 246 } 247 } 248 catch (RollerException re) 249 { 250 mLogger.error("Error getting thread manager", re); 251 } 252 catch (InterruptedException e) 253 { 254 mLogger.error("Error executing operation", e); 255 } 256 } 257 258 261 public void executeIndexOperationNow(final IndexOperation op) 262 { 263 try 264 { 265 if(this.searchEnabled) { 267 mLogger.debug("Executing index operation now: "+op.getClass().getName()); 268 RollerFactory.getRoller().getThreadManager().executeInForeground(op); 269 } 270 } 271 catch (RollerException re) 272 { 273 mLogger.error("Error getting thread manager", re); 274 } 275 catch (InterruptedException e) 276 { 277 mLogger.error("Error executing operation", e); 278 } 279 } 280 281 public synchronized void resetSharedReader() 282 { 283 reader = null; 284 } 285 public synchronized IndexReader getSharedIndexReader() 286 { 287 if (reader == null) 288 { 289 try 290 { 291 reader = IndexReader.open(getIndexDirectory()); 292 } 293 catch (IOException e) 294 { 295 } 296 } 297 return reader; 298 } 299 300 307 public Directory getIndexDirectory() 308 { 309 if (useRAMIndex) 310 { 311 return fRAMindex; 312 } 313 else 314 { 315 return getFSDirectory(false); 316 } 317 } 318 319 private boolean indexExists() 320 { 321 return IndexReader.indexExists(indexDir); 322 } 323 324 Directory getFSDirectory(boolean delete) 325 { 326 Directory directory = null; 327 328 try 329 { 330 directory = FSDirectory.getDirectory(indexDir, delete); 331 } 332 catch (IOException e) 333 { 334 mLogger.error("Problem accessing index directory", e); 335 } 336 337 return directory; 338 } 339 340 private void createIndex(Directory dir) 341 { 342 IndexWriter writer = null; 343 344 try 345 { 346 writer = new IndexWriter(dir, IndexManagerImpl.getAnalyzer(), true); 347 } 348 catch (IOException e) 349 { 350 mLogger.error("Error creating index", e); 351 } 352 finally 353 { 354 try 355 { 356 if (writer != null) 357 { 358 writer.close(); 359 } 360 } 361 catch (IOException e) 362 { 363 } 364 } 365 } 366 367 private IndexOperation getSaveIndexOperation() 368 { 369 return new WriteToIndexOperation(this) { 370 public void doRun() 371 { 372 Directory dir = getIndexDirectory(); 373 Directory fsdir = getFSDirectory(true); 374 375 IndexWriter writer = null; 376 377 try 378 { 379 writer = new IndexWriter(fsdir, IndexManagerImpl 380 .getAnalyzer(), true); 381 382 writer.addIndexes(new Directory[] { dir }); 383 indexConsistencyMarker.delete(); 384 } 385 catch (IOException e) 386 { 387 mLogger.error("Problem saving index to disk", e); 388 389 getFSDirectory(true); 392 } 393 finally 394 { 395 try 396 { 397 if (writer != null) 398 writer.close(); 399 } 400 catch (IOException e1) 401 { 402 mLogger.warn("Unable to close IndexWriter."); 403 } 404 } 405 406 } 407 }; 408 } 409 410 public void release() 411 { 412 } 414 415 public void shutdown() 416 { 417 if (useRAMIndex) 418 { 419 scheduleIndexOperation(getSaveIndexOperation()); 420 } 421 else 422 { 423 indexConsistencyMarker.delete(); 424 } 425 426 try 427 { 428 if (reader != null) 429 reader.close(); 430 } 431 catch (IOException e) 432 { 433 } 435 } 436 } | Popular Tags |