search.jsp revision 125
394N/A<%--
394N/ACDDL HEADER START
394N/A
394N/AThe contents of this file are subject to the terms of the
394N/ACommon Development and Distribution License (the "License").
394N/AYou may not use this file except in compliance with the License.
394N/A
394N/ASee LICENSE.txt included in this distribution for the specific
394N/Alanguage governing permissions and limitations under the License.
394N/A
394N/AWhen distributing Covered Code, include this CDDL HEADER in each
394N/Afile and include the License file at LICENSE.txt.
394N/AIf applicable, add the following below this CDDL HEADER, with the
394N/Afields enclosed by brackets "[]" replaced with your own identifying
394N/Ainformation: Portions Copyright [yyyy] [name of copyright owner]
394N/A
394N/ACDDL HEADER END
394N/A
394N/ACopyright 2005 Sun Microsystems, Inc. All rights reserved.
394N/AUse is subject to license terms.
1874N/A
394N/Aident "%Z%%M% %I% %E% SMI"
394N/A
394N/A--%><%@ page import = "javax.servlet.*,
394N/Ajava.lang.Integer,
394N/Ajavax.servlet.http.*,
394N/Ajava.util.Hashtable,
394N/Ajava.util.Vector,
618N/Ajava.util.Date,
394N/Ajava.util.ArrayList,
394N/Ajava.util.List,
844N/Ajava.lang.*,
844N/Ajava.io.*,
394N/Ajava.io.StringReader,
1273N/Aorg.opensolaris.opengrok.analysis.*,
394N/Aorg.opensolaris.opengrok.search.*,
394N/Aorg.opensolaris.opengrok.web.*,
394N/Aorg.opensolaris.opengrok.web.*,
394N/Aorg.opensolaris.opengrok.search.context.*,
394N/Aorg.opensolaris.opengrok.configuration.*,
394N/Aorg.apache.lucene.search.spell.LuceneDictionary,
1874N/Aorg.apache.lucene.search.spell.SpellChecker,
394N/Aorg.apache.lucene.store.FSDirectory,
1874N/Aorg.apache.lucene.analysis.*,
394N/Aorg.apache.lucene.document.*,
394N/Aorg.apache.lucene.index.*,
394N/Aorg.apache.lucene.search.*,
394N/Aorg.apache.lucene.queryParser.*"
394N/A%><%@ page session="false" %><%@ page errorPage="error.jsp" %><%
394N/ADate starttime = new Date();
String q = request.getParameter("q");
String defs = request.getParameter("defs");
String refs = request.getParameter("refs");
String hist = request.getParameter("hist");
String path = request.getParameter("path");
%>
<%@ include file="projects.jspf" %>
<%
String sort = null;
final String LASTMODTIME = "lastmodtime";
final String RELEVANCY = "relevancy";
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("OpenGrok/sorting")) {
sort = cookie.getValue();
if (!LASTMODTIME.equals(sort) && !RELEVANCY.equals(sort)) {
sort = null;
}
break;
}
}
}
String sortParam = request.getParameter("sort");
if (sortParam != null) {
if (LASTMODTIME.equals(sortParam)) {
sort = LASTMODTIME;
} else if (RELEVANCY.equals(sortParam)) {
sort = RELEVANCY;
}
if (sort != null) {
Cookie cookie = new Cookie("OpenGrok/sorting", sort);
response.addCookie(cookie);
}
}
Hits hits = null;
String errorMsg = null;
String context = request.getContextPath();
if( q!= null && q.equals("")) q = null;
if( defs != null && defs.equals("")) defs = null;
if( refs != null && refs.equals("")) refs = null;
if( hist != null && hist.equals("")) hist = null;
if( path != null && path.equals("")) path = null;
if (project != null && project.equals("")) project = null;
if (q != null || defs != null || refs != null || hist != null || path != null) {
Searcher searcher = null; //the searcher used to open/search the index
IndexReader ireader = null; //the reader used to open/search the index
Query query = null, defQuery = null; //the Query created by the QueryParser
int start = 0; //the first index displayed on this page
int max = 25; //the maximum items displayed on this page
int thispage = 0; //used for the for/next either max or
String moreUrl = null;
CompatibleAnalyser analyzer = new CompatibleAnalyser();
String qstr = "";
String result = "";
try {
String DATA_ROOT = env.getDataRootPath();
if(DATA_ROOT.equals("")) {
throw new Exception("DATA_ROOT parameter is not configured in web.xml!");
}
File data_root = new File(DATA_ROOT);
if(!data_root.isDirectory()) {
throw new Exception("DATA_ROOT parameter in web.xml does not exist or is not a directory!");
}
ireader = IndexReader.open(DATA_ROOT + "/index");
searcher = new IndexSearcher(ireader);
//String date = request.getParameter("date");
try {
start = Integer.parseInt(request.getParameter("start")); //parse the max results first
max = Integer.parseInt(request.getParameter("n")); //then the start index
if(max < 0 || (max % 10 != 0) || max > 50) max = 25;
if(start < 0 ) start = 0;
} catch (Exception e) { }
StringBuilder sb = new StringBuilder();
if (q != null) {
sb.append(q);
}
if (defs != null) {
sb.append(" defs:(");
sb.append(defs);
sb.append(")");
}
if (refs != null) {
sb.append(" refs:(");
sb.append(refs);
sb.append(")");
}
if (path != null) {
sb.append(" path:(");
sb.append(path);
sb.append(")");
}
if (hist != null) {
sb.append(" hist:(");
sb.append(hist);
sb.append(")");
}
if (project != null) {
sb.append(" (");
boolean first = true;
for (String s : project.split(" ")) {
if (first) {
first = false;
} else {
sb.append(" OR ");
}
sb.append("project:(");
sb.append(s);
sb.append(")");
}
sb.append(")");
}
qstr = sb.toString();
QueryParser qparser = new QueryParser("full", analyzer);
qparser.setDefaultOperator(QueryParser.AND_OPERATOR);
qparser.setAllowLeadingWildcard(env.isAllowLeadingWildcard());
query = qparser.parse(qstr); //parse the
if ("lastmodtime".equals(sort)) {
hits = searcher.search(query, new Sort("date", true));
} else {
hits = searcher.search(query);
}
thispage = max;
} catch (BooleanQuery.TooManyClauses e) {
errorMsg = "<b>Error:</b> Too many results for wildcard!";
} catch (ParseException e) {
errorMsg = "<b>Error:</b><br/>" + Util.Htmlize(qstr) + "<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());
}
// @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 (hits != null && hits.length() == 1 && request.getServletPath().equals("/s") && (query != null && query instanceof TermQuery)) {
response.sendRedirect(context + "/xref" + hits.doc(0).get("path")
+ "#" + ((TermQuery)query).getTerm().text());
} else {
%><?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
<head>
<meta name="robots" content="noindex,nofollow">
<link rel="icon" href="img/icon.png" type="image/png"/>
<link rel="stylesheet" type="text/css" href="style.css"/>
<link rel="stylesheet" type="text/css" href="print.css" media="print" />
<link rel="alternate stylesheet" type="text/css" media="all" title="Paper White" href="print.css"/>
<title>Search</title>
</head>
<body>
<div id="page">
<div id="header">
<%= getServletContext().getInitParameter("HEADER") %>
</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"><%
{
StringBuffer url = request.getRequestURL();
url.append('?');
String querys = request.getQueryString();
if (querys != null) {
int idx = querys.indexOf("sort=");
if (idx == -1) {
url.append(querys);
url.append('&');
} else {
url.append(querys.substring(0, idx));
}
}
url.append("sort=");
if (sort == null || RELEVANCY.equals(sort)) {
url.append(LASTMODTIME);
%><b>Sort by relevance</b> <a href="<%=url.toString()%>">Sort by last modified time</a><%
} else {
url.append(RELEVANCY);
%><a href="<%=url.toString()%>">Sort by relevance</a> <b>Sort by last modified time</b><%
}
} %></td></tr></table>
</div>
<div id="menu">
<%@ include file="menu.jspf"%>
</div>
<div id="results">
<%
if( hits == null || errorMsg != null) {
%><%=errorMsg%><%
} else if (hits.length() == 0) {
File spellIndex = new File(env.getDataRootPath(), "spellIndex");
if (spellIndex.exists()) {
FSDirectory spellDirectory = FSDirectory.getDirectory(spellIndex);
SpellChecker checker = new SpellChecker(spellDirectory);
Date sstart = new Date();
%><p><font color="#cc0000">Did you mean</font>:<%
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(), 3);
for(int i = 0;i < ret.length; i++) {
%> <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(), 3);
for(int i = 0;i < ret.length; i++) {
%> <a href=search?q=<%=ret[i]%>><%=ret[i]%></a> &nbsp; <%
}
}
}
}
}
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(), 3);
for(int i = 0;i < ret.length; i++) {
%> <a href=search?q=<%=ret[i]%>><%=ret[i]%></a> &nbsp; <%
}
}
}
}
}
spellDirectory.close();
%></p><%
}
%><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 < hits.length()) {
if((start + max) < hits.length()) {
thispage = max;
} else {
thispage = hits.length() - start;
}
String 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)) +
(sort == null ? "" : "&amp;sort=" + Util.URIEncode(sort));
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<hits.length() && 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 < hits.length()) {
arr = "&gt;&gt;";
} else {
arr = label < 10 ? " " + label : String.valueOf(label);
}
slider.append("<a class=\"more\" href=\"search?n=" + max + "&amp;start=" + i + url + "\">"+
arr + "</a>");
}
label++;
}
} else {
thispage = hits.length() - 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><%=hits.length()%></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);
if(sourceContext != null)
summer = new Summarizer(query, analyzer);
} 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) {
}
Results.prettyPrintHTML(hits, start, start+thispage,
out,
sourceContext, historyContext, summer,
context + "/xref",
context + "/more",
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 (ireader != null)
ireader.close();
} else { // Entry page show the map
response.sendRedirect(context + "/index.jsp");
}
%>