1 package org.roller.presentation.velocity; 2 3 import java.io.IOException ; 4 import java.io.UnsupportedEncodingException ; 5 import java.util.Date ; 6 import java.util.Map ; 7 import java.util.Set ; 8 import java.util.TreeMap ; 9 import java.util.TreeSet ; 10 11 import javax.servlet.ServletException ; 12 import javax.servlet.http.HttpServletRequest ; 13 import javax.servlet.http.HttpServletResponse ; 14 import javax.servlet.jsp.JspFactory ; 15 import javax.servlet.jsp.PageContext ; 16 17 import org.apache.commons.collections.comparators.ReverseComparator; 18 import org.apache.commons.logging.Log; 19 import org.apache.commons.logging.LogFactory; 20 import org.apache.lucene.document.Document; 21 import org.apache.lucene.search.Hits; 22 import org.apache.velocity.Template; 23 import org.apache.velocity.context.Context; 24 import org.roller.RollerException; 25 import org.roller.business.search.FieldConstants; 26 import org.roller.business.search.operations.SearchOperation; 27 import org.roller.config.RollerConfig; 28 import org.roller.model.IndexManager; 29 import org.roller.model.Roller; 30 import org.roller.model.UserManager; 31 import org.roller.model.WeblogManager; 32 import org.roller.pojos.WeblogCategoryData; 33 import org.roller.pojos.WeblogEntryComparator; 34 import org.roller.pojos.WeblogEntryData; 35 import org.roller.pojos.WebsiteData; 36 import org.roller.presentation.RollerContext; 37 import org.roller.presentation.RollerRequest; 38 import org.roller.util.DateUtil; 39 import org.roller.util.StringUtils; 40 41 42 49 public class SearchServlet extends BasePageServlet 50 { 51 static final long serialVersionUID = -2150090108300585670L; 53 54 private static Log mLogger = 55 LogFactory.getFactory().getInstance(SearchServlet.class); 56 57 58 private static int LIMIT = 10; 59 60 61 private static int OFFSET = 0; 62 63 64 private boolean searchEnabled = true; 65 66 67 69 public Template handleRequest(HttpServletRequest request, 70 HttpServletResponse response, Context ctx) throws Exception 71 { 72 String enabled = RollerConfig.getProperty("search.enabled"); 73 if("false".equalsIgnoreCase(enabled)) 74 this.searchEnabled = false; 75 76 if(! this.searchEnabled) { 77 Template outty = null; 78 Exception pageException = null; 79 try { 80 ContextLoader.setupContext( 81 ctx, RollerRequest.getRollerRequest(request), response ); 82 outty = getTemplate( "searchdisabled.vm", "UTF-8" ); 83 } catch (Exception e) { 84 pageException = e; 85 response.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR ); 86 } 87 88 if (pageException != null) { 89 mLogger.error("EXCEPTION: in RollerServlet", pageException); 90 request.setAttribute("DisplayException", pageException); 91 } 92 return outty; 93 } 94 95 mLogger.debug("handleRequest()"); 98 try 99 { 100 request.setCharacterEncoding("UTF-8"); 102 } 103 catch (UnsupportedEncodingException e) 104 { 105 throw new ServletException ("Can't set incoming encoding to UTF-8"); 106 } 107 108 ctx.put("term", ""); 109 ctx.put("hits", new Integer (0)); 110 ctx.put("searchResults", new TreeMap ()); 111 request.setAttribute("zzz_VelocityContext_zzz", ctx); 113 114 mLogger.debug("q = "+request.getParameter("q")); 115 116 if (StringUtils.isEmpty(request.getParameter("q"))) 118 { 119 return generalSearchResults(request, response, ctx); 120 } 121 122 boolean userSpecificSearch = checkForUser(request); 123 try 124 { 125 RollerRequest rreq = getRollerRequest(request, response); 126 127 SearchOperation search = 128 new SearchOperation(rreq.getRoller().getIndexManager()); 129 search.setTerm(request.getParameter("q")); 130 ctx.put("term", request.getParameter("q")); 131 132 WebsiteData website = null; 133 if (userSpecificSearch) 134 { 135 website = rreq.getWebsite(); 136 search.setUsername(rreq.getUser().getUserName()); 137 ctx.put("username", rreq.getUser().getUserName()); 138 } 139 140 if (StringUtils.isNotEmpty(request.getParameter("c"))) 141 { 142 search.setCategory(request.getParameter("c")); 143 } 144 145 executeSearch(rreq.getRoller(), search); 147 148 Map searchResults = new TreeMap (); 149 if (search.getResultsCount() == -1) 150 { 151 ctx.put("errorMessage", "There was a problem with your search."); 154 } 155 else 156 { 157 Hits hits = search.getResults(); 159 searchResults = convertHitsToEntries(rreq, website, hits); 160 ctx.put("offset", request.getAttribute("offset")); 161 ctx.put("limit", request.getAttribute("limit")); 162 163 if (request.getAttribute("categories") != null) 164 { 165 Set cats = (Set )request.getAttribute("categories"); 166 if (cats.size() > 0) 167 { 168 ctx.put("categories", cats); 169 } 170 } 171 } 172 ctx.put("searchResults", searchResults); 173 ctx.put("hits", new Integer (search.getResultsCount())); 174 } 175 catch (Exception e) 176 { 177 mLogger.error("EXCEPTION: in SearchServlet", e); 178 request.setAttribute("DisplayException", e); 179 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 180 } 181 182 if (userSpecificSearch) 183 { 184 return super.handleRequest(request, response, ctx); 185 } 186 187 return generalSearchResults(request, response, ctx); 188 } 189 190 194 private void executeSearch(Roller roller, SearchOperation search) 195 throws RollerException 196 { 197 IndexManager indexMgr = roller.getIndexManager(); 198 indexMgr.executeIndexOperationNow(search); 199 if (mLogger.isDebugEnabled()) 200 { 201 mLogger.debug("numresults = " + search.getResultsCount()); 202 } 203 } 204 205 215 private TreeMap convertHitsToEntries( 216 RollerRequest rreq, WebsiteData website, Hits hits) 217 throws RollerException, IOException 218 { 219 int offset = useOffset(rreq.getRequest()); 221 if (offset >= hits.length()) offset = OFFSET; 222 rreq.getRequest().setAttribute("offset", new Integer (offset)); 223 224 int limit = useLimit(rreq.getRequest()); 226 rreq.getRequest().setAttribute("limit", new Integer (limit)); 227 if (offset + limit > hits.length()) limit = hits.length()-offset; 228 229 boolean userSpecificSearch = checkForUser(rreq.getRequest()); 230 TreeMap searchResults = new TreeMap (new ReverseComparator()); 231 TreeSet categories = new TreeSet (); 232 UserManager userMgr = 233 RollerContext.getRoller(rreq.getRequest()).getUserManager(); 234 WeblogManager weblogMgr = 235 RollerContext.getRoller(rreq.getRequest()).getWeblogManager(); 236 WeblogEntryData entry; 237 Document doc = null; 238 String username = null; 239 for (int i = offset; i < offset+limit; i++) 240 { 241 entry = null; 243 doc = hits.doc(i); 244 username = 245 doc.getField(FieldConstants.USERNAME).stringValue(); 246 247 if (userSpecificSearch && website != null) 248 { 249 if (username.equals(rreq.getUser().getUserName())) 251 { 252 254 entry = weblogMgr.retrieveWeblogEntry( 256 doc.getField(FieldConstants.ID).stringValue() ); 257 } 258 } 259 else 260 { 261 website = userMgr.getWebsite(username); 262 if (website != null) 264 { 265 entry = buildSearchEntry(website, doc); 266 if (doc.getField(FieldConstants.CATEGORY) != null) 267 { 268 categories.add( 269 doc.getField(FieldConstants.CATEGORY) 270 .stringValue()); 271 } 272 } 273 } 274 275 if (entry != null) 278 { 279 addToSearchResults(searchResults, entry); 280 } 281 } 282 rreq.getRequest().setAttribute("categories", categories); 283 return searchResults; 284 } 285 286 290 private int useOffset(HttpServletRequest request) 291 { 292 int offset = OFFSET; 293 if (request.getParameter("o") != null) 294 { 295 try 296 { 297 offset = Integer.valueOf(request.getParameter("o")).intValue(); 298 } 299 catch (NumberFormatException e) 300 { 301 } 303 } 304 return offset; 305 } 306 307 311 private int useLimit(HttpServletRequest request) 312 { 313 int limit = LIMIT; 314 if (request.getParameter("n") != null) 315 { 316 try 317 { 318 limit = Integer.valueOf(request.getParameter("n")).intValue(); 319 } 320 catch (NumberFormatException e) 321 { 322 } 324 } 325 return limit; 326 } 327 328 333 private RollerRequest getRollerRequest(HttpServletRequest request, HttpServletResponse response) 334 { 335 PageContext pageContext = 336 JspFactory.getDefaultFactory() 337 .getPageContext(this, request, response, "", true, 8192, true); 338 339 return RollerRequest.getRollerRequest(pageContext); 341 } 342 343 347 private void addToSearchResults(TreeMap searchResults, WeblogEntryData entry) 348 { 349 Date midnight = DateUtil.getStartOfDay( entry.getPubTime() ); 351 352 TreeSet set = (TreeSet ) searchResults.get(midnight); 355 if (set == null) 356 { 357 set = new TreeSet ( new WeblogEntryComparator() ); 359 searchResults.put(midnight, set); 360 } 361 set.add(entry); 362 } 363 364 369 private WeblogEntryData buildSearchEntry(WebsiteData website, Document doc) 370 { 371 String pubTimeStr = doc.getField(FieldConstants.PUBLISHED).stringValue(); 372 WeblogEntryData entry = new WeblogEntryData(); 373 entry.setWebsite(website); 374 entry.setTitle(doc.getField(FieldConstants.TITLE).stringValue()); 375 entry.setAnchor(doc.getField(FieldConstants.ANCHOR).stringValue()); 376 entry.setPubTime( DateUtil.parseTimestampFromFormats(pubTimeStr) ); 377 entry.setText( doc.getField(FieldConstants.CONTENT_STORED).stringValue() ); 378 if (doc.getField(FieldConstants.CATEGORY) != null) 379 { 380 WeblogCategoryData category = new WeblogCategoryData(); 381 category.setWebsite(website); 382 category.setName(doc.getField(FieldConstants.CATEGORY).stringValue()); 383 entry.setCategory( category ); 384 } 385 return entry; 386 } 387 388 397 private Template generalSearchResults(HttpServletRequest request, HttpServletResponse response, Context ctx) 398 { 399 Template outty = null; 400 Exception pageException = null; 401 try 402 { 403 ContextLoader.setupContext( 404 ctx, RollerRequest.getRollerRequest(request), response ); 405 outty = getTemplate( "searchresults.vm", "UTF-8" ); 406 } 407 catch (Exception e) 408 { 409 pageException = e; 410 response.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR ); 411 } 412 413 if (pageException != null) 414 { 415 mLogger.error("EXCEPTION: in RollerServlet", pageException); 416 request.setAttribute("DisplayException", pageException); 417 } 418 return outty; 419 } 420 421 427 private boolean checkForUser(HttpServletRequest request) 428 { 429 if (StringUtils.isNotEmpty( 430 request.getParameter(RollerRequest.USERNAME_KEY))) 431 { 432 return true; 433 } 434 435 String pathInfoStr = request.getPathInfo(); 436 pathInfoStr = (pathInfoStr!=null) ? pathInfoStr : ""; 437 438 String [] pathInfo = StringUtils.split(pathInfoStr,"/"); 439 if ( pathInfo.length > 0 ) 440 { 441 return true; } 443 return false; 444 } 445 446 } 447 | Popular Tags |