search.jsp revision 1111
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson<%--
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonCDDL HEADER START
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonThe contents of this file are subject to the terms of the
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonCommon Development and Distribution License (the "License").
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonYou may not use this file except in compliance with the License.
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonSee LICENSE.txt included in this distribution for the specific
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonlanguage governing permissions and limitations under the License.
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonWhen distributing Covered Code, include this CDDL HEADER in each
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonfile and include the License file at LICENSE.txt.
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonIf applicable, add the following below this CDDL HEADER, with the
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonfields enclosed by brackets "[]" replaced with your own identifying
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsoninformation: Portions Copyright [yyyy] [name of copyright owner]
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonCDDL HEADER END
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonCopyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson--%><%@ page import = "javax.servlet.*,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonjava.lang.Integer,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonjavax.servlet.http.*,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonjava.util.Hashtable,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonjava.util.Vector,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonjava.util.Date,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonjava.util.ArrayList,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonjava.util.List,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonjava.lang.*,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonjava.io.*,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonjava.io.StringReader,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.opensolaris.opengrok.analysis.*,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.opensolaris.opengrok.index.IndexDatabase,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.opensolaris.opengrok.search.*,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.opensolaris.opengrok.web.*,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.opensolaris.opengrok.search.context.*,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.opensolaris.opengrok.configuration.*,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.apache.lucene.search.spell.LuceneDictionary,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.apache.lucene.search.spell.SpellChecker,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.apache.lucene.search.SortField,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.apache.lucene.search.TopScoreDocCollector,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.apache.lucene.store.FSDirectory,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.apache.lucene.analysis.*,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.apache.lucene.document.*,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.apache.lucene.search.*,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonorg.apache.lucene.queryParser.*"
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson%><%@ page session="false" %><%@ page errorPage="error.jsp" %><%
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonDate starttime = new Date();
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonString q = request.getParameter("q");
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonString defs = request.getParameter("defs");
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonString refs = request.getParameter("refs");
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonString hist = request.getParameter("hist");
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonString path = request.getParameter("path");
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson%><%@ include file="projects.jspf" %><%
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonString sort = null;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonfinal String LASTMODTIME = "lastmodtime";
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonfinal String RELEVANCY = "relevancy";
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonfinal String BY_PATH = "fullpath";
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonfinal SortField S_BY_PATH = new SortField(BY_PATH,SortField.STRING);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonCookie[] cookies = request.getCookies();
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonif (cookies != null) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson for (Cookie cookie : cookies) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (cookie.getName().equals("OpenGrok/sorting")) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson sort = cookie.getValue();
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (!LASTMODTIME.equals(sort) && !RELEVANCY.equals(sort) && !BY_PATH.equals(sort)) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson sort = RELEVANCY;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonString sortParam = request.getParameter("sort");
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonif (sortParam != null) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (LASTMODTIME.equals(sortParam)) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson sort = LASTMODTIME;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson } else if (RELEVANCY.equals(sortParam)) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson sort = RELEVANCY;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson } else if (BY_PATH.equals(sortParam)) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson sort = BY_PATH;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (sort != null) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson Cookie cookie = new Cookie("OpenGrok/sorting", sort);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson response.addCookie(cookie);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson} else { sort = RELEVANCY; }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson//List<org.apache.lucene.document.Document> docs=new ArrayList<org.apache.lucene.document.Document>();
7eea693d6b672899726e75993fddc4e95b52647fMark JohnsonString errorMsg = null;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonif( q!= null && q.equals("")) q = null;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonif( defs != null && defs.equals("")) defs = null;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonif( refs != null && refs.equals("")) refs = null;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonif( hist != null && hist.equals("")) hist = null;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonif( path != null && path.equals("")) path = null;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonif (project != null && project.size()<1) project = null;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonif (q != null || defs != null || refs != null || hist != null || path != null) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson Searcher searcher = null; //the searcher used to open/search the index
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson TopScoreDocCollector collector=null; // the collector used
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ScoreDoc[] hits = null; // list of documents which result from the query
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson Query query = null; //the Query created by the QueryBuilder
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson boolean allCollected=false;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int totalHits=0;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int start = 0; //the first index displayed on this page
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson //TODO deprecate max this and merge with paging and param n - TEST needed
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson //int max = 25; //the maximum items displayed on this page
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int max=RuntimeEnvironment.getInstance().getHitsPerPage();
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int hitsPerPage = RuntimeEnvironment.getInstance().getHitsPerPage();
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int cachePages= RuntimeEnvironment.getInstance().getCachePages();
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson final boolean docsScoredInOrder=false;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int thispage = 0; //used for the for/next either max or
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson QueryBuilder queryBuilder =
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson new QueryBuilder()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson .setFreetext(q).setDefs(defs).setRefs(refs)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson .setPath(path).setHist(hist);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson try {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson String DATA_ROOT = env.getDataRootPath();
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if(DATA_ROOT.equals("")) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson throw new Exception("DATA_ROOT parameter is not configured in web.xml!");
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson File data_root = new File(DATA_ROOT);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if(!data_root.isDirectory()) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson throw new Exception("DATA_ROOT parameter in web.xml does not exist or is not a directory!");
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson //String date = request.getParameter("date");
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson try {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson //TODO merge paging hitsPerPage with parameter n (has to reflect the search if changed so proper number is cached first time)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson start = Integer.parseInt(request.getParameter("start")); //parse the max results first
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson max = Integer.parseInt(request.getParameter("n")); //then the start index
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if(max < 0 || (max % 10 != 0) || max > 50) max = 25;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if(start < 0 ) start = 0;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson } catch (Exception e) { }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson query = queryBuilder.build();
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson File root = new File(RuntimeEnvironment.getInstance().getDataRootFile(),
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson "index");
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (RuntimeEnvironment.getInstance().hasProjects()) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (project == null) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson errorMsg = "<b>Error:</b> You must select a project!";
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson } else {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (project.size() > 1) { //more projects
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson IndexSearcher[] searchables = new IndexSearcher[project.size()];
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson File droot = new File(RuntimeEnvironment.getInstance().getDataRootFile(), "index");
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int ii = 0;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson //TODO might need to rewrite to Project instead of String , need changes in projects.jspf too
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson for (String proj : project) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson FSDirectory dir = FSDirectory.open(new File(droot, proj));
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson searchables[ii++] = new IndexSearcher(dir);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (Runtime.getRuntime().availableProcessors() > 1) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson searcher = new ParallelMultiSearcher(searchables);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson } else {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson searcher = new MultiSearcher(searchables);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson } else { // just 1 project selected
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson root = new File(root, project.get(0));
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson FSDirectory dir = FSDirectory.open(root);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson searcher = new IndexSearcher(dir);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson } else { //no project setup
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson FSDirectory dir = FSDirectory.open(root);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson searcher = new IndexSearcher(dir);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson //TODO check if below is somehow reusing sessions so we don't requery again and again, I guess 2min timeout sessions could be usefull, since you click on the next page within 2mins, if not, then wait ;)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (errorMsg == null) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson collector = TopScoreDocCollector.create(hitsPerPage*cachePages,docsScoredInOrder);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (LASTMODTIME.equals(sort)) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson Sort sortf = new Sort(new SortField("date",SortField.STRING,true));
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson TopFieldDocs fdocs=searcher.search(query, null,hitsPerPage*cachePages, sortf);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson totalHits=fdocs.totalHits;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (start>=hitsPerPage*cachePages && !allCollected) { //fetch ALL results only if above cachePages
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson fdocs=searcher.search(query, null, totalHits, sortf);
allCollected=true;
}
hits = fdocs.scoreDocs;
} else if (BY_PATH.equals(sort)) {
Sort sortf = new Sort(S_BY_PATH);
TopFieldDocs fdocs=searcher.search(query, null,hitsPerPage*cachePages, sortf);
totalHits=fdocs.totalHits;
if (start>=hitsPerPage*cachePages && !allCollected) { //fetch ALL results only if above cachePages
fdocs=searcher.search(query, null,totalHits, sortf);
allCollected=true;
}
hits = fdocs.scoreDocs;
} else {
searcher.search(query,collector);
totalHits=collector.getTotalHits();
if (start>=hitsPerPage*cachePages && !allCollected) { //fetch ALL results only if above cachePages
collector = TopScoreDocCollector.create(totalHits,docsScoredInOrder);
searcher.search(query,collector);
allCollected=true;
}
hits=collector.topDocs().scoreDocs;
}
//below will get all the documents
// for (int i = 0; i < hits.length; i++) {
// int docId = hits[i].doc;
// Document d = searcher.doc(docId);
// docs.add(d);
// }
}
thispage = max;
} catch (BooleanQuery.TooManyClauses e) {
errorMsg = "<b>Error:</b> Too many results for wildcard!";
} catch (ParseException e) {
errorMsg = "<b>Error parsing your query</b>" +
"<p/>You might try to enclose your search term in quotes, " +
"<a href=\"help.jsp#escaping\">escape special characters</a> " +
"with <b>\\</b>, or read the <a href=\"help.jsp\">Help</a> " +
"on the query language.<p/>" +
"Error message from parser:<br/>" + Util.htmlize(e.getMessage());
} catch (FileNotFoundException e) {
errorMsg = "<b>Error:</b> Index database not found";
} catch (Exception e) {
errorMsg = "<b>Error:</b> " + Util.htmlize(e.getMessage());
}
// Bug #3900: Check if this is a search for a single term, and that term
// is a definition. If that's the case, and we only have one match, we'll
// generate a direct link instead of a listing.
boolean isSingleDefinitionSearch =
(query instanceof TermQuery) && (defs != null);
// Attempt to create a direct link to the definition if we search for one
// single definition term AND we have exactly one match AND there is only
// one definition of that symbol in the document that matches.
boolean uniqueDefinition = false;
if (isSingleDefinitionSearch && hits != null && hits.length == 1) {
Document doc = searcher.doc(hits[0].doc);
if (doc.getFieldable("tags")!=null) {
byte[] rawTags = doc.getFieldable("tags").getBinaryValue();
Definitions tags = Definitions.deserialize(rawTags);
String symbol = ((TermQuery) query).getTerm().text();
if (tags.occurrences(symbol) == 1) {
uniqueDefinition = true;
}
}
}
// @TODO fix me. I should try to figure out where the exact hit is instead
// of returning a page with just _one_ entry in....
if (uniqueDefinition && request.getServletPath().equals(Constants.searchR)) {
String preFragmentPath = Util.URIEncodePath(context + Constants.xrefP + searcher.doc(hits[0].doc).get("path"));
String fragment = Util.URIEncode(((TermQuery)query).getTerm().text());
StringBuilder url = new StringBuilder(preFragmentPath);
url.append("#");
url.append(fragment);
response.sendRedirect(url.toString());
} else {
String pageTitle = "Search";
RuntimeEnvironment environment = RuntimeEnvironment.getInstance();
environment.register();
%><%@ include file="httpheader.jspf" %>
<body>
<div id="page">
<div id="header"><%@ include file="pageheader.jspf" %></div>
<div id="Masthead"></div>
<div id="bar">
<table border="0" width="100%"><tr><td><a href="<%=context%>/" id="home">Home</a></td><td align="right"><%
{
String url = "search?";
url = url + (q == null ? "" : "&amp;q=" + Util.URIEncode(q)) +
(defs == null ? "" : "&amp;defs=" + Util.URIEncode(defs)) +
(refs == null ? "" : "&amp;refs=" + Util.URIEncode(refs)) +
(path == null ? "" : "&amp;path=" + Util.URIEncode(path)) +
(hist == null ? "" : "&amp;hist=" + Util.URIEncode(hist));
if (hasProjects) {
if (project!=null) {
url = url + "&amp;project=";
for (Iterator it = project.iterator(); it.hasNext();) {
url = url + (project == null ? "" : Util.URIEncode((String) it.next()) + ",");
}
}
}
%>Sort by: <%
url=url+("&amp;sort=");
if (sort == null || RELEVANCY.equals(sort)) {
%><b>relevance</b> | <a href="<%=url+LASTMODTIME%>">last modified time</a> | <a href="<%=url+BY_PATH%>">path</a><%
} else if (LASTMODTIME.equals(sort)) {
%><a href="<%=url+RELEVANCY%>">relevance</a> | <b>last modified time</b> | <a href="<%=url+BY_PATH%>">path</a><%
} else if (BY_PATH.equals(sort)) {
%><a href="<%=url+RELEVANCY%>">relevance</a> | <a href="<%=url+LASTMODTIME%>">last modified time</a> | <b>path</b><%
} else {
%><a href="<%=url+RELEVANCY%>">relevance</a> | <a href="<%=url+LASTMODTIME%>">last modified time</a> | <a href="<%=url+BY_PATH%>">path</a><%
}
} %></td></tr></table>
</div>
<div id="menu">
<%@ include file="menu.jspf"%>
</div>
<div id="results">
<%
//TODO spellchecking cycle below is not that great and we only create suggest links for every token in query, not for a query as whole
if( hits == null || errorMsg != null) {
%><%=errorMsg%><%
} else if (hits.length == 0) {
File spellIndex = new File(env.getDataRootPath(), "spellIndex");
File[] spellIndexes=null;
if (RuntimeEnvironment.getInstance().hasProjects()) {
if (project.size() > 1) { //more projects
spellIndexes = new File[project.size()];
int ii = 0;
//TODO might need to rewrite to Project instead of String , need changes in projects.jspf too
for (String proj : project) {
spellIndexes[ii++] = new File(spellIndex,proj);
}
} else { // just 1 project selected
spellIndex = new File(spellIndex, project.get(0));
}
}
int count=1;
if (spellIndexes!=null) {count=spellIndexes.length;}
for (int idx = 0; idx < count; idx++) {
if (spellIndexes!=null) spellIndex = spellIndexes[idx];
if (spellIndex.exists()) {
FSDirectory spellDirectory = FSDirectory.open(spellIndex);
SpellChecker checker = new SpellChecker(spellDirectory);
Date sstart = new Date();
boolean printHeader = true;
String[] toks;
if(q != null) {
toks = q.split("[\t ]+");
if(toks != null){
for(int j=0; j<toks.length; j++) {
if(toks[j].length() > 3) {
String[] ret = checker.suggestSimilar(toks[j].toLowerCase(), 5);
for(int i = 0;i < ret.length; i++) {
if (printHeader) {
%><p><font color="#cc0000">Did you mean(for <%=spellIndex.getName()%>)</font>:<%
printHeader = false;
}
%> <a href=search?q=<%=ret[i]%>><%=ret[i]%></a> &nbsp; <%
}
}
}
}
}
if(refs != null) {
toks = refs.split("[\t ]+");
if(toks != null){
for(int j=0; j<toks.length; j++) {
if(toks[j].length() > 3) {
String[] ret = checker.suggestSimilar(toks[j].toLowerCase(), 5);
for(int i = 0;i < ret.length; i++) {
if (printHeader) {
%><p><font color="#cc0000">Did you mean(for <%=spellIndex.getName()%>)</font>:<%
printHeader = false;
}
%> <a href=search?refs=<%=ret[i]%>><%=ret[i]%></a> &nbsp; <%
}
}
}
}
}
//TODO it seems the only true spellchecker is for below field, see IndexDatabase createspellingsuggestions ...
if(defs != null) {
toks = defs.split("[\t ]+");
if(toks != null){
for(int j=0; j<toks.length; j++) {
if(toks[j].length() > 3) {
String[] ret = checker.suggestSimilar(toks[j].toLowerCase(), 5);
for(int i = 0;i < ret.length; i++) {
if (printHeader) {
%><p><font color="#cc0000">Did you mean(for <%=spellIndex.getName()%>)</font>:<%
printHeader = false;
}
%> <a href=search?defs=<%=ret[i]%>><%=ret[i]%></a> &nbsp; <%
}
}
}
}
}
if (printHeader) {
%></p><%
}
spellDirectory.close();
checker.close();
}
}
%><p> Your search <b><%=query.toString()%></b> did not match any files.
<br />
Suggestions:<br/><blockquote>- Make sure all terms are spelled correctly.<br/>
- Try different keywords.<br/>
- Try more general keywords.<br/>
- Use 'wil*' cards if you are looking for partial match.
</blockquote>
</p><%
} else { // We have a lots of results to show
StringBuilder slider = null;
if ( max < totalHits) {
if((start + max) < totalHits) {
thispage = max;
} else {
thispage = totalHits - start;
}
String urlp = (q == null ? "" : "&amp;q=" + Util.URIEncode(q)) +
(defs == null ? "" : "&amp;defs=" + Util.URIEncode(defs)) +
(refs == null ? "" : "&amp;refs=" + Util.URIEncode(refs)) +
(path == null ? "" : "&amp;path=" + Util.URIEncode(path)) +
(hist == null ? "" : "&amp;hist=" + Util.URIEncode(hist)) +
(sort == null ? "" : "&amp;sort=" + Util.URIEncode(sort));
if (hasProjects) {
urlp = urlp + "&amp;project=";
for (Iterator it = project.iterator(); it.hasNext();) {
urlp = urlp + (project == null ? "" : Util.URIEncode((String) it.next()) + ",");
}
}
slider = new StringBuilder();
int labelStart =1;
int sstart = start - max* (start / max % 10 + 1) ;
if(sstart < 0) {
sstart = 0;
labelStart = 1;
} else {
labelStart = sstart/max + 1;
}
int label = labelStart;
int labelEnd = label + 11;
String arr;
for(int i=sstart; i<totalHits && label <= labelEnd; i+= max) {
if (i <= start && start < i+ max) {
slider.append("<span class=\"sel\">" + label + "</span>");
} else {
if(label == labelStart && label != 1) {
arr = "&lt;&lt";
} else if(label == labelEnd && i < totalHits) {
arr = "&gt;&gt;";
} else {
arr = label < 10 ? " " + label : String.valueOf(label);
}
slider.append("<a class=\"more\" href=\"s?n=" + max + "&amp;start=" + i + urlp + "\">"+
arr + "</a>");
}
label++;
}
} else {
thispage = totalHits - start; // set the max index to max or last
}
%>&nbsp; &nbsp; Searched <b><%=query.toString()%></b> (Results <b><%=start+1%> -
<%=thispage+start%></b> of <b><%=totalHits%></b>) sorted by <%=sort%> <p><%=slider != null ?
slider.toString(): ""%></p>
<table width="100%" cellpadding="3" cellspacing="0" border="0"><%
Context sourceContext = null;
Summarizer summer = null;
if (query != null) {
try{
sourceContext =
new Context(query, queryBuilder.getQueries());
if(sourceContext != null)
summer = new Summarizer(query,
new CompatibleAnalyser());
} catch (Exception e) {
}
}
HistoryContext historyContext = null;
try {
historyContext = new HistoryContext(query);
} catch (Exception e) {
}
EftarFileReader ef = null;
try{
ef = new EftarFileReader(env.getDataRootPath() + "/index/dtags.eftar");
} catch (Exception e) {
}
//TODO also fix the way what and how it is passed to prettyprint, can improve performance! SearchEngine integration is really needed here.
Results.prettyPrintHTML(searcher,hits, start, start+thispage,
out,
sourceContext, historyContext, summer,
context,
env.getSourceRootPath(),
env.getDataRootPath(),
ef);
if(ef != null) {
try{
ef.close();
} catch (IOException e) {
}
}
%></table><br/>
<b> Completed in <%=(new Date()).getTime() - starttime.getTime()%> milliseconds </b> <br/>
<%=slider != null ? "<p>" + slider + "</p>" : ""%>
<%
}
%><br/></div><%@include file="foot.jspf"%><%
}
if (searcher != null) {
searcher.close();
}
} else { // Entry page show the map
response.sendRedirect(context + "/index.jsp");
}
%>