NIHVIVO-1187 Migrate handling of empty or invalid query from PagedSearchController to FreemarkerPagedSearchController
This commit is contained in:
parent
a3f4487a90
commit
51e294d1af
7 changed files with 138 additions and 35 deletions
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
19
webapp/web/templates/freemarker/body/search/search-form.ftl
Normal file
19
webapp/web/templates/freemarker/body/search/search-form.ftl
Normal 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")}
|
18
webapp/web/templates/freemarker/body/search/search-help.ftl
Normal file
18
webapp/web/templates/freemarker/body/search/search-help.ftl
Normal 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>
|
35
webapp/web/templates/search/searchBadQuery.jsp
Normal file
35
webapp/web/templates/search/searchBadQuery.jsp
Normal 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 -->
|
Loading…
Add table
Reference in a new issue