View Javadoc

1   package org.paneris.bibliomania;
2   
3   import java.util.Enumeration;
4   
5   import javax.servlet.http.HttpServletRequest;
6   
7   import org.melati.Melati;
8   import org.melati.servlet.Form;
9   import org.melati.poem.AccessToken;
10  import org.melati.poem.Persistent;
11  import org.melati.poem.PoemTask;
12  import org.melati.poem.PoemThread;
13  import org.melati.poem.UnexpectedExceptionPoemException;
14  import org.melati.template.ServletTemplateContext;
15  import org.paneris.bibliomania.fti.ContextSearchResults;
16  import org.paneris.bibliomania.fti.HitText;
17  import org.paneris.bibliomania.fti.IndexOther;
18  import org.paneris.bibliomania.fti.Library;
19  import org.paneris.bibliomania.fti.Score;
20  import org.paneris.bibliomania.fti.ScoredHitTextsEnumeration;
21  import org.paneris.bibliomania.fti.SearchResults;
22  import org.webmacro.WebMacroException;
23  import org.webmacro.servlet.HandlerException;
24  import org.webmacro.servlet.WebContext;
25  
26  import com.sleepycat.db.DatabaseException;
27  
28  public class Search extends BibliomaniaServlet {
29  
30    private static final long serialVersionUID = 1L;
31  
32    protected String bibliomaniaHandle(Melati melati, WebContext context) throws WebMacroException {
33      ServletTemplateContext tc = melati.getServletTemplateContext();
34      String queryText = Form.getFieldNulled(tc, "queryText");
35      String queryHeadwords = Form.getFieldNulled(tc, "queryHeadwords");  // No longer in form
36  
37      if (queryText == null && queryHeadwords == null)
38        return bibliomaniaTemplate("search/Search.wm");
39  
40      context.put("queryText", queryText == null ? "" : queryText);
41      context.put("queryHeadwords", queryHeadwords == null ? "" : queryHeadwords);
42  
43      int start = 0;
44      String startString = context.getForm("start");
45      if (startString != null) {
46        try {
47          start = Math.max(0, Integer.parseInt(startString));
48        } catch (NumberFormatException e) {
49          throw new HandlerException("`start' param must be a number");
50        }
51      }
52  
53      BibliomaniaDatabase bib = (BibliomaniaDatabase)PoemThread.database();
54      
55      if (!bib.openBerkelyDBs()) { 
56        context.put("message", "Full text search has been temporarily switched off, sorry.");      
57      } else  { 
58        
59        boolean infoSearch = "true".equals(context.getForm("info"));
60  
61        IndexOther fti = infoSearch ? bib.infoFTI() : bib.fti();
62        Library lib = infoSearch ? bib.infoLibrary() : bib.getChapterTable();
63        context.put("info", infoSearch ? Boolean.TRUE : null);
64  
65        SearchResults raw;
66        try {
67          raw = fti.querySearchResults(queryText, queryHeadwords);
68          PoemThread.toTidy().add(raw);
69        } catch (DatabaseException e) {
70          throw new HandlerException(
71            "Problem with Full Text index:" + e.toString());
72        }
73  
74        ContextSearchResults results;
75        results = new ContextSearchResults(lib, raw, fti);
76        PoemThread.toTidy().add(results);
77  
78        String hitsPerTextString = context.getForm("hitsPerText");
79        int hitsPerText;
80        if (hitsPerTextString != null && !hitsPerTextString.trim().equals(""))
81          try {
82            hitsPerText = Math.max(0, Integer.parseInt(hitsPerTextString));
83            if (hitsPerText == 0)
84              hitsPerText =
85                ((BibliomaniaDatabase)melati.getDatabase())
86                  .getDefaultSearchHitsPerText();
87          } catch (NumberFormatException e) {
88            throw new HandlerException("`hitsPerText' param must be a number");
89          } else
90            hitsPerText =
91            ((BibliomaniaDatabase)melati.getDatabase())
92              .getDefaultSearchHitsPerText();
93  
94        long startTextID = 0;
95        long limitTextID = Long.MAX_VALUE;
96  
97        boolean restrict = "true".equals(context.getForm("restrict"));
98  
99        if (restrict) {
100         Persistent object = melati.getObject();
101         if (object != null && object instanceof Unit) {
102           startTextID = ((Unit)object).ftiTextID_start();
103           limitTextID = ((Unit)object).ftiTextID_limit();
104        }
105       }
106       context.put("restrict", restrict ? "true" : "false");
107 
108       Score.Hit[] order;
109       try {
110         order = Score.scoredHits(raw, startTextID, limitTextID, 50 /* FIXME */
111         );
112       } catch (DatabaseException e) {
113         throw new HandlerException(
114           "Problem with Full Text index:" + e.toString());
115       }
116 
117       ScoredHitTextsEnumeration hits =
118         new ScoredHitTextsEnumeration(
119           results,
120           order,
121           start,
122           bib.getSearchHitsPerPage(),
123           hitsPerText);
124       context.put("hitTexts", hits);
125       context.put("count", order.length);
126 
127       context.put("hitsPerText", new Integer(hitsPerText));
128 
129       context.put("start", new Integer(hits.getPageStart()));
130       context.put("end", new Integer(hits.getPageEnd()));
131 
132       HttpServletRequest req = context.getRequest();
133 
134       Integer prevStart = hits.getPrevPageStart();
135       if (prevStart != null)
136         context.put(
137           "prevPageURI",
138           req.getRequestURI()
139             + "?"
140             + Form.sameQueryWith(
141               req.getQueryString(),
142               "start",
143               prevStart.toString()));
144 
145       Integer nextStart = hits.getNextPageStart();
146       if (nextStart != null)
147         context.put(
148           "nextPageURI",
149           req.getRequestURI()
150             + "?"
151             + Form.sameQueryWith(
152               req.getQueryString(),
153               "start",
154               nextStart.toString()));
155     }
156     return bibliomaniaTemplate("search/Results.wm");
157   }
158 
159   public static void main(final String[] args) throws Exception {
160     IndexOther.debug = true;
161 
162     final BibliomaniaDatabase bib = new BibliomaniaDatabase(false);
163     bib.connect("bibliomania",
164       "org.melati.poem.dbms.Postgresql",
165       "jdbc:postgresql:bibliomania",
166       "postgres",
167       "*",
168       8);
169 
170     bib.inSession(AccessToken.root, new PoemTask() {
171       public void run() {
172         try {
173           SearchResults raw = bib.fti().querySearchResults(args[0]);
174 
175           int hitsPerText = 10;
176 
177           long startTextID;
178           if (args.length < 3)
179             startTextID = 0L;
180           else if (args[1].equals("tid"))
181             startTextID = Long.parseLong(args[2]);
182           else
183             startTextID =
184               ((Unit)bib
185                 .getTable(args[1])
186                 .getObject(Integer.parseInt(args[2])))
187                 .ftiTextID_start();
188 
189           long limitTextID;
190           if (args.length < 5)
191             limitTextID = Long.MAX_VALUE;
192           else if (args[3].equals("tid"))
193             limitTextID = Long.parseLong(args[4]);
194           else
195             limitTextID =
196               ((Unit)bib
197                 .getTable(args[3])
198                 .getObject(Integer.parseInt(args[4])))
199                 .ftiTextID_start();
200 
201           System.err.println("[ " + startTextID + ", " + limitTextID + ")");
202 
203           Score.Hit[] order =
204             Score.scoredHits(raw, startTextID, limitTextID, 50);
205 
206           ContextSearchResults results =
207             new ContextSearchResults(bib.getChapterTable(), raw, bib.fti());
208 
209           Enumeration hits =
210             new ScoredHitTextsEnumeration(
211               results,
212               order,
213               0,
214               bib.getSearchHitsPerPage(),
215               hitsPerText);
216 
217           while (hits.hasMoreElements())
218              ((HitText)hits.nextElement()).dump();
219         } catch (Exception e) {
220           throw new UnexpectedExceptionPoemException(e);
221         }
222       }
223     });
224   }
225 }