package org.bigbluebutton.webminer.web.controller; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.apache.lucene.document.Document; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.Searcher; import org.apache.lucene.search.TopDocCollector; import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.TopFieldDocs; import org.springframework.validation.BindException; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.SimpleFormController; import org.bigbluebutton.webminer.index.Index; import org.bigbluebutton.webminer.search.Search; import org.bigbluebutton.webminer.web.model.MatchVO; import org.bigbluebutton.webminer.web.model.SearchCriteriaCommand; import org.bigbluebutton.webminer.web.model.SessionHitsOrganizer; public class SearchController extends SimpleFormController { /* * (non-Javadoc) * * @seeorg.springframework.web.servlet.mvc.SimpleFormController# * processFormSubmission(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse, java.lang.Object, * org.springframework.validation.BindException) */ private static Logger logger = Logger.getLogger(SearchController.class); @Override protected ModelAndView processFormSubmission(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception { return super.processFormSubmission(request, response, command, errors); } /* * (non-Javadoc) * * @see * org.springframework.web.servlet.mvc.SimpleFormController#onSubmit(javax * .servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, * java.lang.Object, org.springframework.validation.BindException) */ @Override protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception { SearchCriteriaCommand srchCriteriaCommand = (SearchCriteriaCommand) command; int startFrom = (new Integer(srchCriteriaCommand.getStartFrom())).intValue(); int endIndex = 0; String queryStr = srchCriteriaCommand.getKeyWords(); String sortBy = srchCriteriaCommand.getSort(); String operator = srchCriteriaCommand.getOperator(); String relRange = srchCriteriaCommand.getRangeValue(); boolean bSmart = (relRange!=null)&&(!relRange.isEmpty()); boolean bSortByScore = sortBy.equalsIgnoreCase("byScore"); if (logger.isInfoEnabled()) { logger.info("---search offset="+startFrom+" sortBy="+sortBy+"qryString="+queryStr+"operator="+operator); } Map<String, Object> model = new HashMap<String, Object>(); LinkedHashMap<String, MatchVO> sortedMap = new LinkedHashMap<String, MatchVO>(); Map<String, SessionHitsOrganizer> hitsOrganizerMap = new HashMap<String, SessionHitsOrganizer>(); Map<String, String> resultMap = new HashMap<String, String>(); synchronized (Index.getInstance()) { Search search = Search.getInstance(); search.startSearch(); TopDocs tps = null; Searcher searcher = null; ScoreDoc[] hits = null; if (bSortByScore){ Search.TopDocCollectorSearchResult result = search.searchByScore(queryStr, startFrom, operator); TopDocCollector collector = result.getCollector(); if (collector != null) { tps = collector.topDocs(); } hits = tps.scoreDocs; searcher = result.getSearcher(); } else { Search.TopFieldDocsSearchResult result = search.searchBySession(queryStr, startFrom, operator); TopFieldDocs tfd = result.getTopFieldDocs(); if (tfd!=null){ hits = tfd.scoreDocs; } searcher = result.getSearcher(); } if (hits == null) { if (logger.isInfoEnabled()) { logger.info("---No hit"); } } else { int start = startFrom; int end = hits.length; endIndex = end; if (logger.isInfoEnabled()) { logger.info("total match number="+endIndex); } String currentSession="0"; String lastSession="0"; SessionHitsOrganizer hitsOrganizer = null; for (int i = start; i < end; i++) { float score = hits[i].score; Document doc = searcher.doc(hits[i].doc); String path = doc.get("path"); if (path != null) { MatchVO matchVO = new MatchVO(); matchVO.setFilePath(path); String fullContent = doc.get("title"); String summary = getKeywordContext(queryStr, fullContent); matchVO.setContentSummary(summary); String fileName = doc.get("fileName"); matchVO.setFileName(fileName); String indexSummary = doc.get("summary"); matchVO.setIndexingSummary(indexSummary); matchVO.setScore(score); String title = indexSummary+": "+fileName+" (Match Score = "+score+")"; //String content = doc.get("contents"); String allData=title+"%"+summary; if (doc.get("slideTime")!=null){ allData += "%"+doc.get("slideTime"); matchVO.setSlidePlayTime(doc.get("slideTime")); } //sortedMap.put(path, allData); sortedMap.put(path, matchVO); //model.put(path, newTitle+"%"+doc.get("summary")+"%"+doc.get("slideTime")); if (logger.isInfoEnabled()) { logger.info("----"+allData); logger.info((i + 1) + ". " + path); } if (title != null) { if (logger.isInfoEnabled()) { logger.info(" Title: " + doc.get("title")); } } if (bSmart){ //Prepare for the grouping results currentSession = getSessionNumberFromFileURL(path); //get existing current session organizer hitsOrganizer = hitsOrganizerMap.get(currentSession); if (hitsOrganizer==null){ //create a new session organizer object hitsOrganizer = new SessionHitsOrganizer(); hitsOrganizer.setSessionNum(currentSession); hitsOrganizerMap.put(currentSession, hitsOrganizer); } hitsOrganizer.setReleventRange((new Float(relRange)).floatValue()); hitsOrganizer.addExactHits(path, score); matchVO.setSessionHitOrganier(hitsOrganizer); } } else { System.out.println((i + 1) + ". " + "No path for this document"); } } } search.finishSearch(); //post processing for result grouping... Iterator hitsOrganizerIt = hitsOrganizerMap.keySet().iterator(); while (hitsOrganizerIt.hasNext()){ String key = (String) hitsOrganizerIt.next(); SessionHitsOrganizer organizer = hitsOrganizerMap.get(key); organizer.generateResultGroup(); } model.put("result", sortedMap); if (bSmart){ model.put("hitsOrganizer", hitsOrganizerMap); } model.put("searchKeyword", queryStr); model.put("startFrom", (new Integer(startFrom)).toString()); model.put("endAt", (new Integer(endIndex)).toString()); model.put("sortBy",sortBy); model.put("operator",operator); model.put("rangeValue",relRange); } ModelAndView mav = new ModelAndView(this.getSuccessView(), model); return mav; } private String getKeywordContext(String keyWord, String fullText) { String[] contentTokens = fullText.split(","); // If there is only one token, return the entire matched content String rtnValue = fullText; for (int i = 0; i < contentTokens.length; i++) { if (contentTokens[i].indexOf(keyWord) > -1) { rtnValue = contentTokens[i]; break; } } return rtnValue; } private String getSessionNumberFromFileURL(String filePath) { String[] pathTokens = filePath.split("/"); String rtnValue = pathTokens[pathTokens.length - 3]; return rtnValue; } private LinkedHashMap groupResultBySession(LinkedHashMap singleHitMap, int extdRange) { LinkedHashMap extdResultMap = new LinkedHashMap<String, Object>(); int lastSessionNum = 0; int currentSessionNum = 0; // return extdResultMap; } }