1 53 54 106 107 package com.Yasna.forum.database; 108 109 import java.util.Date ; 110 import java.util.Iterator ; 111 import java.io.IOException ; 112 import java.io.File ; 113 114 import org.apache.lucene.analysis.*; 115 import org.apache.lucene.analysis.standard.*; 116 import org.apache.lucene.document.*; 117 import org.apache.lucene.store.*; 118 import org.apache.lucene.search.*; 119 import org.apache.lucene.queryParser.*; 120 import org.apache.lucene.index.*; 121 122 import com.Yasna.forum.*; 123 124 127 public class DbQuery implements com.Yasna.forum.Query { 128 129 134 private String queryString = ""; 135 private java.util.Date beforeDate = null; 136 private java.util.Date afterDate = null; 137 private User user = null; 138 private ForumThread thread = null; 139 140 143 private int [] results = null; 144 145 private Forum forum; 146 private DbForumFactory factory; 147 148 151 private static final int MAX_RESULTS_SIZE = 500; 152 153 private static String indexPath = null; 154 private static IndexReader reader; 155 private static Searcher searcher; 156 private static Directory searchDirectory = null; 157 private static long indexLastModified; 158 private static Analyzer analyzer = new StandardAnalyzer(); 159 160 public DbQuery(Forum forum, DbForumFactory factory){ 161 this.forum = forum; 162 this.factory = factory; 163 } 164 public DbQuery(DbForumFactory factory){ 165 this.factory = factory; 166 this.forum = null; 167 } 168 169 public void setQueryString(String queryString) { 170 this.queryString = queryString; 171 results = null; 173 } 174 175 public String getQueryString() { 176 return queryString; 177 } 178 179 public void setBeforeDate(java.util.Date beforeDate) { 180 this.beforeDate = beforeDate; 181 results = null; 183 } 184 185 public java.util.Date getBeforeDate() { 186 return beforeDate; 187 } 188 189 public void setAfterDate(java.util.Date afterDate){ 190 this.afterDate = afterDate; 191 results = null; 193 } 194 195 public java.util.Date getAfterDate(){ 196 return afterDate; 197 } 198 199 public User getFilteredUser() { 200 return user; 201 } 202 203 public void filterOnUser(User user) { 204 this.user = user; 205 results = null; 206 } 207 208 public ForumThread getFilteredThread() { 209 return thread; 210 } 211 212 public void filterOnThread(ForumThread thread) { 213 this.thread = thread; 214 results = null; 215 } 216 217 public int resultCount() { 218 if (results == null) { 219 executeQuery(); 220 } 221 return results.length; 222 } 223 224 public Iterator results() { 225 if (results == null) { 226 executeQuery(); 227 } 228 return new DbQueryIterator(results, factory); 229 } 230 231 public Iterator results(int startIndex, int numResults){ 232 if (results == null) { 233 executeQuery(); 234 } 235 return new DbQueryIterator(results, factory, startIndex, numResults); 236 } 237 238 241 private void executeQuery() { 242 try { 243 Searcher searcher = getSearcher(); 244 if (searcher == null) { 245 results = new int[0]; 247 return; 248 } 249 250 org.apache.lucene.search.Query bodyQuery = 251 QueryParser.parse(queryString, "body", analyzer); 252 253 org.apache.lucene.search.Query subjectQuery = 254 QueryParser.parse(queryString, "subject", analyzer); 255 256 257 BooleanQuery comboQuery = new BooleanQuery(); 258 comboQuery.add(subjectQuery,false,false); 259 comboQuery.add(bodyQuery,false,false); 260 261 MultiFilter multiFilter = new MultiFilter(2); 262 multiFilter.add(new FieldFilter("Indexer", "FORUMS")); 264 265 if(forum!=null){ String forumID = Integer.toString(forum.getID()); 268 multiFilter.add(new FieldFilter("forumID", forumID)); 269 } 270 271 if (beforeDate != null || afterDate != null) { 273 if (beforeDate != null && afterDate != null) { 274 multiFilter.add(new DateFilter("creationDate", beforeDate, afterDate)); 275 } 276 else if (beforeDate == null) { 277 multiFilter.add(DateFilter.After("creationDate", afterDate)); 278 } 279 else { 280 multiFilter.add(DateFilter.Before("creationDate", beforeDate)); 281 } 282 } 283 284 if (user != null) { 286 String userID = Integer.toString(user.getID()); 287 multiFilter.add(new FieldFilter("userID", userID)); 288 } 289 290 if (thread != null) { 292 String threadID = Integer.toString(thread.getID()); 293 multiFilter.add(new FieldFilter("threadID", threadID)); 294 } 295 296 Hits hits = searcher.search(comboQuery, multiFilter); 297 int numResults = hits.length() < MAX_RESULTS_SIZE ? 299 hits.length() : MAX_RESULTS_SIZE; 300 int [] messages = new int[numResults]; 301 for (int i=0; i<numResults; i++) { 302 messages[i] = Integer.parseInt( ((Document)hits.doc(i)).get("messageID") ); 303 } 304 results = messages; 305 } 306 catch (Exception e) { 307 e.printStackTrace(); 308 results = new int[0]; 309 } 310 } 311 312 323 private static Searcher getSearcher() throws IOException { 324 if (indexPath == null) { 325 String yazdHome = PropertyManager.getProperty("yazdHome"); 328 if (yazdHome == null) { 329 System.err.println("ERROR: the yazdHome property is not set."); 330 throw new IOException ("Unable to open index for searching " + 331 "because yazdHome was not set."); 332 } 333 indexPath = yazdHome + File.separator + "search"; 334 } 335 336 if (searcher == null) { 337 synchronized(analyzer) { 339 if (searcher == null) { 340 if (indexExists(indexPath)) { 341 searchDirectory = FSDirectory.getDirectory(indexPath, false); 342 reader = IndexReader.open(searchDirectory); 343 indexLastModified = reader.lastModified(searchDirectory); 344 searcher = new IndexSearcher(reader); 345 } 346 else { 348 return null; 349 } 350 } 351 } 352 } 353 if (reader.lastModified(searchDirectory) > indexLastModified) { 354 synchronized (analyzer) { 355 if (reader.lastModified(searchDirectory) > indexLastModified) { 356 if (indexExists(indexPath)) { 357 indexLastModified = reader.lastModified(searchDirectory); 358 reader.close(); 361 362 searchDirectory = FSDirectory.getDirectory(indexPath, false); 363 reader = IndexReader.open(searchDirectory); 364 searcher = new IndexSearcher(reader); 365 } 366 else { 368 return null; 369 } 370 } 371 } 372 } 373 return searcher; 374 } 375 376 381 private static boolean indexExists(String indexPath) { 382 File segments = new File (indexPath + File.separator + "segments"); 385 return segments.exists(); 386 } 387 } 388 | Popular Tags |