NIHVIVO-1187 Migrate handling of empty or invalid query from PagedSearchController to FreemarkerPagedSearchController

This commit is contained in:
rjy7 2010-10-01 20:53:13 +00:00
parent a3f4487a90
commit 51e294d1af
7 changed files with 138 additions and 35 deletions

View file

@ -70,14 +70,14 @@ public class Controllers {
public static final String TAB_PRIMARY_JSP = "/templates/tabs/tabprimary.jsp";
public static final String ALPHA_INDEX_JSP = "/templates/alpha/alphaIndex.jsp";
public static final String SEARCH_BASIC_JSP = "/templates/search/searchBasic.jsp";
public static final String SEARCH_PAGED_JSP = "/templates/search/searchPaged.jsp";
public static final String SEARCH_FAILED_JSP = "/templates/search/searchFailed.jsp";
public static final String SEARCH_GROUP_JSP = "/templates/search/searchGroup.jsp";
public static final Object SEARCH_FORM_JSP = "/templates/search/searchForm.jsp";
public static final Object SEARCH_BAD_QUERY_JSP = "/templates/search/searchBadQuery.jsp";
public static final String BROWSE_GROUP_JSP = "/templates/browse/browseGroup.jsp";
public static final String HORIZONTAL_JSP = "/templates/edit/fetch/horizontal.jsp";

View file

@ -27,6 +27,7 @@ import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
@ -72,7 +73,6 @@ import edu.cornell.mannlib.vitro.webapp.utils.Html2Text;
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.IndividualTemplateModel;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.LinkTemplateModel;
import freemarker.template.Configuration;
/**
* PagedSearchController is the new search controller that interacts
@ -88,14 +88,26 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(FreemarkerPagedSearchController.class.getName());
private static final String TEMPLATE_SEARCH_RESULTS = "search-pagedResults.ftl";
private static final String TEMPLATE_ERROR = "search-error.ftl";
String NORESULT_MSG = "The search returned no results.";
private IndexSearcher searcher = null;
private int defaultHitsPerPage = 25;
private int defaultMaxSearchSize= 1000;
protected enum SearchTemplate {
PAGED_RESULTS("search-pagedResults.ftl"),
FORM("search-form.ftl"),
ERROR("search-error.ftl"),
BAD_QUERY("search-badQuery.ftl");
private final String filename;
SearchTemplate(String filename) {
this.filename = filename;
}
public String toString() {
return filename;
}
}
public void init(ServletConfig config) throws ServletException {
super.init(config);
@ -158,13 +170,15 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple
String qtxt = vreq.getParameter(VitroQuery.QUERY_PARAMETER_NAME);
Analyzer analyzer = getAnalyzer(getServletContext());
Query query = getQuery(vreq, portalFlag, analyzer, indexDir, qtxt);
log.debug("query for '" + qtxt +"' is " + query.toString());
if (query == null ) {
return doNoQuery(portal);
}
Query query = null;
try {
query = getQuery(vreq, portalFlag, analyzer, indexDir, qtxt);
log.debug("query for '" + qtxt +"' is " + query.toString());
} catch (ParseException e) {
return doBadQuery(portal, qtxt);
}
IndexSearcher searcherForRequest = getIndexSearcher(indexDir);
TopDocs topDocs = null;
@ -295,7 +309,7 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple
return doSearchError(e);
}
return new TemplateResponseValues(TEMPLATE_SEARCH_RESULTS, body);
return new TemplateResponseValues(SearchTemplate.PAGED_RESULTS.toString(), body);
}
private void alphaSortIndividuals(List<Individual> beans) {
@ -510,7 +524,7 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple
}
private Query getQuery(VitroRequest request, PortalFlag portalState,
Analyzer analyzer, String indexDir, String querystr ) throws SearchException{
Analyzer analyzer, String indexDir, String querystr ) throws SearchException, ParseException {
Query query = null;
try{
//String querystr = request.getParameter(VitroQuery.QUERY_PARAMETER_NAME);
@ -572,7 +586,9 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple
log.debug("Query: " + query);
}catch (Exception ex){
} catch (ParseException e) {
throw new ParseException(e.getMessage());
} catch (Exception ex){
throw new SearchException(ex.getMessage());
}
@ -756,20 +772,20 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple
private TemplateResponseValues doSearchError(String message) {
Map<String, Object> body = new HashMap<String, Object>();
body.put("message", "Search failed: " + message);
return new TemplateResponseValues(TEMPLATE_ERROR, body);
return new TemplateResponseValues(SearchTemplate.ERROR.toString(), body);
}
private ExceptionResponseValues doSearchError(Throwable e) {
Map<String, Object> body = new HashMap<String, Object>();
body.put("message", "Search failed: " + e.getMessage());
return new ExceptionResponseValues(TEMPLATE_ERROR, body, e);
return new ExceptionResponseValues(SearchTemplate.ERROR.toString(), body, e);
}
private TemplateResponseValues doNoQuery(Portal portal) {
private TemplateResponseValues doBadQuery(Portal portal, String query) {
Map<String, Object> body = new HashMap<String, Object>();
body.put("title", "Search " + portal.getAppName());
body.put("message", "No query entered.");
return new TemplateResponseValues(TEMPLATE_ERROR, body);
body.put("query", query);
return new TemplateResponseValues(SearchTemplate.BAD_QUERY.toString(), body);
}
private TemplateResponseValues doFailedSearch(String message, String querytext) {
@ -779,14 +795,14 @@ public class FreemarkerPagedSearchController extends FreemarkerHttpServlet imple
message = "Search failed.";
}
body.put("message", message);
return new TemplateResponseValues(TEMPLATE_ERROR, body);
return new TemplateResponseValues(SearchTemplate.ERROR.toString(), body);
}
private TemplateResponseValues doNoHits(String querytext) {
Map<String, Object> body = new HashMap<String, Object>();
body.put("title", "Search for '" + querytext + "'");
body.put("message", "No matching results.");
return new TemplateResponseValues(TEMPLATE_ERROR, body);
return new TemplateResponseValues(SearchTemplate.ERROR.toString(), body);
}
/**

View file

@ -29,6 +29,7 @@ import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
@ -150,13 +151,17 @@ public class PagedSearchController extends VitroHttpServlet implements Searcher{
String qtxt = vreq.getParameter(VitroQuery.QUERY_PARAMETER_NAME);
Analyzer analyzer = getAnalyzer(getServletContext());
Query query = getQuery(vreq, portalFlag, analyzer, indexDir, qtxt);
log.debug("query for '" + qtxt +"' is " + query.toString());
if (query == null ) {
doNoQuery(request, response);
Query query = null;
try {
query = getQuery(vreq, portalFlag, analyzer, indexDir, qtxt);
} catch (ParseException e) {
log.warn("Query parse exception: " + e);
doBadQuery(qtxt, request, response);
return;
}
}
log.debug("query for '" + qtxt +"' is " + query.toString());
IndexSearcher searcherForRequest = getIndexSearcher(indexDir);
@ -426,7 +431,7 @@ public class PagedSearchController extends VitroHttpServlet implements Searcher{
}
private Query getQuery(VitroRequest request, PortalFlag portalState,
Analyzer analyzer, String indexDir, String querystr ) throws SearchException{
Analyzer analyzer, String indexDir, String querystr ) throws SearchException, ParseException {
Query query = null;
try{
//String querystr = request.getParameter(VitroQuery.QUERY_PARAMETER_NAME);
@ -495,8 +500,10 @@ public class PagedSearchController extends VitroHttpServlet implements Searcher{
}
log.debug("Query: " + query);
}catch (Exception ex){
} catch (ParseException e) {
throw new ParseException(e.getMessage());
} catch (Exception ex){
throw new SearchException(ex.getMessage());
}
@ -677,12 +684,13 @@ public class PagedSearchController extends VitroHttpServlet implements Searcher{
}
}
private void doNoQuery(HttpServletRequest request,
private void doBadQuery(String queryStr, HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
Portal portal = (new VitroRequest(request)).getPortal();
request.setAttribute("title", "Search "+portal.getAppName());
request.setAttribute("bodyJsp", Controllers.SEARCH_FORM_JSP);
request.setAttribute("bodyJsp", Controllers.SEARCH_BAD_QUERY_JSP);
request.setAttribute("queryStr", queryStr);
RequestDispatcher rd = request
.getRequestDispatcher(Controllers.BASIC_JSP);

View file

@ -0,0 +1,7 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<div class="contents searchFailed">
<p class="warning">Your query '${query}' was invalid. Please modify your search and try again.</p>
<#include "search-form.ftl">
</div>

View file

@ -0,0 +1,19 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<div class="contents searchForm">
<div class="advancedSearchForm">
<form name="filterForm" method="post" action="search">
<h3>Search</h3>
<input class="top_padded" name="querytext" value="" type="text" size="50" />
<p><input class="form-button" value="Search" type="submit"/></p>
</form>
</div><!--advancedSearchForm-->
<div class="searchTips">
<#include "search-help.ftl">
</div>
</div>
${stylesheets.addFromTheme("/css/search.css")}

View file

@ -0,0 +1,18 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<h3>Search Tips</h3>
<ul>
<li>Use short, single terms unless your searches are returning too many results</li>
<li>When you enter more than one term, the search will look for records containing <strong>all</strong> of them unless you add the word "OR" between your terms.</li>
<li>"NOT" can help limit searches -- e.g., <i>climate NOT change</i></li>
<li>Except for boolean operators, searches are <strong>not</strong> case-sensitive, so "Geneva" and "geneva" are equivalent</li>
<li>Enclose a phrase in quotes (") to search for the whole phrase, not individual words (e.g., "protein folding") -- <i>both leading and ending quotes are required</i></li>
<li>Phrase searches may be combined with boolean operators: <i>"climate change" OR "global warming"</i></li>
<li>The search uses <strong>stemming</strong> by default so that close word variations will also be found (e.g., "sequence" also matches "sequences" and "sequencing").
Use the wildcard <strong>*</strong> character to match wider variation (e.g., <strong>nano*</strong> to match both
<i>nanotechnology</i> and <i>nanofabrication</i>), but note that searching uses <i>stemmed</i>, or shortened, versions of words,
so "cogniti*" finds nothing while "cognit*" finds both <i>cognitive</i> and <i>cognition</i></li>
<li>If you're not sure of the spelling, put a <strong>~</strong> at the end -- e.g., <i>cabage~</i> finds <i>cabbage</i>,
<i>steven~</i> finds <i>Stephen</i> and <i>Stefan</i> (as well as a few unwanted extra words)</li>
<li>To match a person or unit's primary entry, enter <i>name: Smith</i> or <i>name: Biology</i></li>
</ul>

View file

@ -0,0 +1,35 @@
<%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %><%/* this odd thing points to something in web.xml */ %>
<%@ page errorPage="/error.jsp"%>
<% /***********************************************
Used when the search results are empty.
request.attributes:
request.parameters:
None yet.
Consider sticking < % = MiscWebUtils.getReqInfo(request) % > in the html output
for debugging info.
**********************************************/
%>
<c:set var='lists' value='${requestScope.collatedResultsLists}'/>
<c:set var='groupNames' value='${requestScope.collatedGroupNames}'/>
<c:set var='portal' value='${requestScope.portal}'/>
<c:set var='portalBean' value='${requestScope.portalBean}'/>
<c:set var='portalId' scope='request' value='${portalBean.portalId}'/>
<c:set var='entitiesListJsp' value='/templates/entity/entityList.jsp'/>
<div id="content">
<div class="contents searchFailed">
<p class="warning">
<c:out value='${requestScope.message}'
default="Your query '${queryStr}' was invalid. Please modify your search and try again."
escapeXml='false'/>
</p>
<jsp:include page="searchForm.jsp"/>
</div><!-- contents -->
</div><!-- content -->