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] + "\n"; text += stripes[curColor++ %2] + "\n"; if (results.size() == 0) return text + "
"; text += "Found " + results.size() + " results for your query: \"" + request.getParameter("query") + "\"
TitleAuthorPage (click to view)
"; 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; } } }