import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
import java.util.*;
import java.net.*;
public class KeywordSearch extends LitsearchBase {
public String drawPage(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String searchType = request.getParameter("type");
String searchQuery = request.getParameter("query");
if (searchQuery == null || searchType == null) {
Template t = new Template(TEMPLATE_DIR + "keywordsearch.html");
return t.toString();
}
searchQuery = searchQuery.trim();
String text = "";
String[] stripes = new String[2];
stripes[0] = "
";
stripes[1] = "
";
int curColor = 0;
ArrayList terms = new ArrayList();
while (true) {
int i = searchQuery.indexOf(' ');
if (i == -1) {
terms.add(PorterStemmer.stem(searchQuery));
break;
}
terms.add(PorterStemmer.stem(searchQuery.substring(0, i)));
searchQuery = searchQuery.substring(i + 1).trim();
}
String highlight = "";
Iterator itr = terms.iterator();
while (itr.hasNext()) {
highlight += (String) itr.next() + ",";
}
ArrayList results = new ArrayList();
if (searchType.equals("all") || terms.size() == 1) {
results = doPageSearch(terms, " AND ");
} else if (searchType.equals("any") && terms.size() > 1) {
results = doPageSearch(terms, " OR ");
} else if (searchType.equals("phrase") && terms.size() > 1) {
results = doPhraseSearch(terms);
}
text += "";
text += stripes[curColor % 2] + "";
text += "Found " + results.size() + " results for your query: \"" +
request.getParameter("query") + "\" | \n";
text += stripes[curColor++ %2] +
"Title | Author | Page (click to view) | \n";
if (results.size() == 0) return text + "
";
ConnectionWrapper wrapper = null;
try {
wrapper = DatabaseHook.getConnection();
Connection c = wrapper.connection();
Statement stmt = c.createStatement();
ResultSet rs;
String query;
itr = results.iterator();
String orClause = "";
boolean firstTime = true;
while (itr.hasNext()) {
if (!firstTime) orClause += " OR ";
else firstTime = false;
String id = (String) itr.next();
orClause += "(u.global_start <= " + id +
" AND u.global_end >= " + id + ")";
}
query = "SELECT w.id, w.title, b.name, u.page " +
"FROM UniquePage u, Work w, WrittenBy b " +
"WHERE (" + orClause +
") AND w.id = u.work AND b.work = w.id " +
"ORDER BY w.title, u.page LIMIT 200";
rs = stmt.executeQuery(query);
while (rs.next()) {
text += stripes[curColor++ % 2];
text += "" +
rs.getString("title") + " | ";
text += "by " + rs.getString("name") + " | ";
text += "page " + rs.getInt("page") + " |
\n";
}
text += stripes[curColor++ % 2];
text += "Search Again\n";
text += " | ";
wrapper.checkIn();
return text;
} catch (Exception e) {
wrapper.checkIn();
throw e;
}
}
public ArrayList doPageSearch(ArrayList terms, String connector) throws Exception {
ConnectionWrapper wrapper = null;
try {
wrapper = DatabaseHook.getConnection();
Connection c = wrapper.connection();
Statement stmt = c.createStatement();
ResultSet rs = null;
String query;
String fromClause = " FROM ";
String whereClause = "";
for (int i = 0; i < terms.size(); i++) {
if (i > 0) {
fromClause += ", ";
whereClause += " AND ";
}
fromClause += "PageContainsWord c" + i + ", Word w" + i + ", UniquePage p" + i;
whereClause += " c" + i + ".word = w" + i + ".id AND p" + i + ".id = c" + i +
".page AND w" + i + ".word=" + formatString((String) terms.get(i));
whereClause += " AND p0.id = p" + i +".id ";
}
ArrayList result = new ArrayList();
query = "SELECT (p0.global_start + 1) " + fromClause + " WHERE " + whereClause + " LIMIT 200";
rs = stmt.executeQuery(query);
while(rs.next()) {
result.add(rs.getString(1));
}
wrapper.checkIn();
//throw new Exception(query);
return result;
} catch (Exception e) {
wrapper.checkIn();
throw e;
}
}
public ArrayList doPhraseSearch(ArrayList terms)throws Exception {
ConnectionWrapper wrapper = null;
ArrayList result = null;
if (terms.size() == 0) return result;
try {
wrapper = DatabaseHook.getConnection();
Connection c = wrapper.connection();
Statement stmt = c.createStatement();
ResultSet rs;
String query;
int offset = 0;
if (terms.size() % 2 == 1) {
ArrayList tmp1 = new ArrayList();
ArrayList tmp2 = new ArrayList();
query = "SELECT DISTINCT i1.gpos " +
"FROM WordInstance i1, Word w1, Word w2 " +
"WHERE w1.id = i1.prev AND w2.id = i1.word " +
"AND w1.word=" + formatString((String) terms.get(0)) +
" AND w2.word=" + formatString((String) terms.get(1));
terms.remove(0);
rs = stmt.executeQuery(query);
while(rs.next()) tmp1.add(rs.getString(1));
query = "SELECT DISTINCT (i1.gpos-1) " +
"FROM WordInstance i1, Word w1, Word w2 " +
"WHERE w1.id = i1.prev AND w2.id = i1.word " +
"AND w1.word=" + formatString((String) terms.get(0)) +
" AND w2.word=" + formatString((String) terms.get(1));
terms.remove(0);
terms.remove(0);
rs = stmt.executeQuery(query);
while(rs.next()) tmp2.add(rs.getString(1));
result = ListOps.intersect(tmp1, tmp2);
offset+=2;
}
while(terms.size() > 0) {
ArrayList tmp = new ArrayList();
query = "SELECT DISTINCT (i1.gpos - " + offset + ") " +
"FROM WordInstance i1, Word w1, Word w2 " +
"WHERE w1.id = i1.prev AND w2.id = i1.word " +
"AND w1.word=" + formatString((String) terms.get(0)) +
" AND w2.word=" + formatString((String) terms.get(1));
terms.remove(0);
terms.remove(0);
rs = stmt.executeQuery(query);
while(rs.next()) tmp.add(rs.getString(1));
if (result == null) result = tmp;
else result = ListOps.intersect(tmp, result);
offset += 2;
}
wrapper.checkIn();
return result;
} catch (Exception e) {
wrapper.checkIn();
throw e;
}
}
}