1 41 package com.mvnforum.search.post; 42 43 import java.io.IOException ; 44 import java.sql.Timestamp ; 45 import java.util.*; 46 47 import com.mvnforum.MVNForumConfig; 48 import com.mvnforum.auth.MVNForumPermission; 49 import com.mvnforum.db.*; 50 import com.mvnforum.search.CombineFilter; 51 import com.mvnforum.search.IntegerFilter; 52 import net.myvietnam.mvncore.exception.DatabaseException; 53 import net.myvietnam.mvncore.exception.ObjectNotFoundException; 54 import org.apache.commons.logging.Log; 55 import org.apache.commons.logging.LogFactory; 56 import org.apache.lucene.analysis.Analyzer; 57 import org.apache.lucene.document.Document; 58 import org.apache.lucene.index.Term; 59 import org.apache.lucene.queryParser.ParseException; 60 import org.apache.lucene.queryParser.QueryParser; 61 import org.apache.lucene.search.*; 62 import org.apache.lucene.store.Directory; 63 64 77 public class PostSearchQuery 78 { 79 private static Log log = LogFactory.getLog(PostSearchQuery.class); 80 81 public static final int SEARCH_ANY_DATE = 0; 83 84 public static final int SEARCH_NEWER = 1; 85 public static final int SEARCH_OLDER = 2; 86 87 public static final int SEARCH_ONLY_TITLE = 1; 89 public static final int SEARCH_ONLY_BODY = 2; 90 91 private int memberID = -1; 92 private int forumId = 0; 93 private boolean withAttachment = false; 95 private int minAttachmentCount = -1; 98 private String searchString = null; 99 100 private Timestamp fromDate = null; 101 private Timestamp toDate = null; 102 103 private int hitCount = 0; 104 private Collection searchResult = null; 105 106 private int scopeInPost = SEARCH_ONLY_TITLE|SEARCH_ONLY_BODY; 108 109 public PostSearchQuery() { 110 } 111 112 116 public void setMemberId(int memberId) { 117 this.memberID = memberId; 118 } 119 120 124 public void setForumId(int forumId) { 125 this.forumId = forumId; 126 } 127 128 132 public void setSearchString(String searchString) { 133 this.searchString = searchString; 134 } 135 136 public void setScopeInPost(int scopeInPost) { 137 this.scopeInPost = scopeInPost; 138 } 139 140 public void setFromDate(Timestamp fromDate) { 141 this.fromDate = fromDate; 142 } 143 144 public void setToDate(Timestamp toDate) { 145 this.toDate = toDate; 146 } 147 148 153 public void setWithAttachment(boolean withAttachment) { 154 this.withAttachment = withAttachment; 155 } 156 157 public void setMinAttachmentCount(int count) { 158 this.minAttachmentCount = count; 159 } 160 161 protected IndexSearcher getSearcher(Directory directory) throws IOException { 163 try { 164 IndexSearcher searcher = new IndexSearcher(directory); 165 return searcher; 166 } catch (IOException ex) { 167 log.error("Cannot access the lucene search index for query. Please check if you have configed mvnForumHome properly. You can also go to Admin Zone to rebuild the Lucene index files.", ex); 170 throw new IOException ("Cannot access the lucene search index. Please report this error to web site Administrator (check mvnForumHome or rebuild Lucene index)."); 172 } 173 } 174 175 public void searchDocuments(int offset, int rowsToReturn, MVNForumPermission permission) 176 throws IOException , DatabaseException, ObjectNotFoundException { 177 178 if ((searchString == null || searchString.equals("")) && 180 (memberID == -1) && 181 (minAttachmentCount < 1)) { 182 return; 184 } 185 BooleanQuery query = new BooleanQuery(); 187 try { 188 Query topicBodyQuery = getTopicBodyQuery(); 189 if (topicBodyQuery != null) { 190 query.add(topicBodyQuery, true, false); 191 log.debug("topicBodyQuery = " + topicBodyQuery); 192 } 193 194 Query withAttachmentQuery = getWithAttachmentQuery(); 195 if (withAttachment) { 196 query.add(withAttachmentQuery, true, false); 197 log.debug("withAttachmentQuery = " + withAttachmentQuery); 198 } 199 200 Query categoryForumQuery = getCategoryForumQuery(permission); 201 if (categoryForumQuery != null) { 202 log.debug("categoryForumQuery = " + categoryForumQuery); 203 query.add(categoryForumQuery, true, false); 204 } 205 206 Query memberQuery = getMemberQuery(); 207 if (memberQuery != null) { 208 log.debug("memberQuery = " + memberQuery); 209 query.add(memberQuery, true, false); 210 } 211 } catch (ParseException pe) { 212 log.error("Cannot parse the search query", pe); 213 } 214 log.debug("booleanQuery = " + query); 215 216 DateFilter dateFilter = null; 217 if (fromDate != null && toDate != null) { 219 dateFilter = new DateFilter(PostIndexer.FIELD_POST_DATE, fromDate, toDate); 220 } else if (fromDate != null) { 221 dateFilter = DateFilter.After(PostIndexer.FIELD_POST_DATE, fromDate); 222 } else if (toDate != null) { 223 dateFilter = DateFilter.Before(PostIndexer.FIELD_POST_DATE, toDate); 224 } 225 226 IntegerFilter attachCountFilter = null; 227 228 if ( minAttachmentCount > 0 ) { 229 attachCountFilter = IntegerFilter.greaterThan(PostIndexer.FIELD_ATTACHMENT_COUNT, minAttachmentCount); 230 } 231 232 Filter filter = null; 233 234 if (dateFilter != null) { 235 if (attachCountFilter != null) { 236 filter = new CombineFilter(dateFilter, attachCountFilter); 237 } else { 238 filter = dateFilter; 239 } 240 } else { 241 filter = attachCountFilter; 242 } 243 244 Directory directory = null; 246 IndexSearcher searcher = null; 247 try { 248 directory = MVNForumConfig.getSearchPostIndexDir(); 249 searcher = getSearcher(directory); 250 251 Hits postHits = null; 253 if (filter != null) { 254 postHits = searcher.search(query, filter); 255 } else { 256 postHits = searcher.search(query); 257 } 258 259 hitCount = postHits.length(); 260 searchResult = getPosts(postHits, offset, rowsToReturn); 261 } catch (IOException ex) { 262 throw ex; 263 } finally { 264 if (searcher != null) { 266 try { 267 searcher.close(); 268 } catch (IOException ex) { 269 log.debug("Error closing Lucene IndexSearcher", ex); 270 } 271 } 272 } 273 } 274 275 public int getHitCount() { 276 return hitCount; 277 } 278 279 public Collection getPostResult() { 280 if (searchResult == null) { 281 searchResult = new ArrayList(); 283 } 284 return searchResult; 285 } 286 287 private Collection getPosts(Hits postHits, int offset, int rowsToReturn) 288 throws IOException , ObjectNotFoundException, DatabaseException { 289 290 if (offset < 0) throw new IllegalArgumentException ("The offset < 0 is not allowed."); 291 if (rowsToReturn <= 0) throw new IllegalArgumentException ("The rowsToReturn <= 0 is not allowed."); 292 293 ArrayList retValue = new ArrayList(hitCount); 295 296 for (int i = offset; (i < offset + rowsToReturn) && (i < hitCount); i++) { 297 Document postDocument = postHits.doc(i); 298 int postID = Integer.parseInt(postDocument.get(PostIndexer.FIELD_POST_ID)); 299 PostBean postBean = DAOFactory.getPostDAO().getPost(postID); 300 retValue.add(postBean); 301 } 302 return retValue; 303 } 304 305 private Query getTopicBodyQuery() throws ParseException { 306 if (searchString == null || searchString.equals("")) { 307 return null; 308 } 309 Analyzer analyzer = PostIndexer.getAnalyzer(); 310 BooleanQuery topicBodyQuery = new BooleanQuery(); 311 312 Query topicQuery = QueryParser.parse(searchString, 314 PostIndexer.FIELD_POST_TOPIC, 315 analyzer); 316 topicBodyQuery.add(topicQuery, false, false); 317 318 Query bodyQuery = QueryParser.parse(searchString, 320 PostIndexer.FIELD_POST_BODY, 321 analyzer); 322 if ( scopeInPost == SEARCH_ONLY_TITLE) { 323 return topicQuery; 324 } else if ( scopeInPost == SEARCH_ONLY_BODY){ 325 return bodyQuery; 326 } 327 topicBodyQuery.add(bodyQuery, false, false); 328 329 return topicBodyQuery; 330 } 331 332 private Query getMemberQuery() { 333 Query memberQuery = null; 334 if (memberID > 0) { 335 Term memberTerm = new Term(PostIndexer.FIELD_MEMBER_ID, String.valueOf(memberID)); 336 memberQuery = new TermQuery(memberTerm); 337 } 338 return memberQuery; 339 } 340 341 private Query getWithAttachmentQuery() { 342 Query withAttachmentQuery = null; 343 if (withAttachment) { 344 Term withAttachmentTerm = new Term(PostIndexer.FIELD_WITH_ATTACHMENT, String.valueOf(withAttachment)); 345 withAttachmentQuery = new TermQuery(withAttachmentTerm); 346 } 347 return withAttachmentQuery; 348 } 349 350 private Query getCategoryForumQuery(MVNForumPermission permission) throws DatabaseException { 351 BooleanQuery categoryForumQuery = new BooleanQuery(); 352 if (forumId == 0) { 353 Collection forumBeans = ForumCache.getInstance().getBeans(); 355 for (Iterator iter = forumBeans.iterator(); iter.hasNext(); ) { 356 ForumBean forumBean = (ForumBean)iter.next(); 357 int currentForumID = forumBean.getForumID(); 358 if ((forumBean.getForumStatus() != ForumBean.FORUM_STATUS_DISABLED) && 359 permission.canReadPost(currentForumID)) { 360 361 Term forumTerm = new Term(PostIndexer.FIELD_FORUM_ID, String.valueOf(currentForumID)); 362 Query forumQuery = new TermQuery(forumTerm); 363 categoryForumQuery.add(forumQuery, false, false); 364 } 365 } 366 } else if (forumId > 0) { 367 Term forumTerm = new Term(PostIndexer.FIELD_FORUM_ID, String.valueOf(forumId)); 369 Query forumQuery = new TermQuery(forumTerm); 370 categoryForumQuery.add(forumQuery, true, false); 371 } else if (forumId < 0) { 372 int categoryID = -forumId; Collection forumBeans = ForumCache.getInstance().getBeans(); 375 for (Iterator iter = forumBeans.iterator(); iter.hasNext(); ) { 376 ForumBean forumBean = (ForumBean)iter.next(); 377 if (forumBean.getCategoryID() == categoryID) { 378 int currentForumID = forumBean.getForumID(); 379 if ((forumBean.getForumStatus() != ForumBean.FORUM_STATUS_DISABLED) && 380 permission.canReadPost(currentForumID)) { 381 382 Term forumTerm = new Term(PostIndexer.FIELD_FORUM_ID, String.valueOf(currentForumID)); 383 Query forumQuery = new TermQuery(forumTerm); 384 categoryForumQuery.add(forumQuery, false, false); 385 } 386 } 387 } 388 } 389 return categoryForumQuery; 390 } 391 } 392 | Popular Tags |