source: trunk/gsdl/src/recpt/queryaction.cpp@ 279

Last change on this file since 279 was 279, checked in by sjboddie, 25 years ago

Now sets "cl" arg to "search" when going to a document from a search
results page. This allows the close book icon (in hierarchy toc) to
take you back to the results page if that's where you came from.
If you got to the document page somehow other than from a
classification or a search (i.e. if "cl" isn't set) then the close
book icon is disabled

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 13.4 KB
Line 
1/**********************************************************************
2 *
3 * queryaction.cpp --
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
6 * PUT COPYRIGHT NOTICE HERE
7 *
8 * $Id: queryaction.cpp 279 1999-06-16 04:03:48Z sjboddie $
9 *
10 *********************************************************************/
11
12/*
13 $Log$
14 Revision 1.5 1999/06/16 04:03:48 sjboddie
15 Now sets "cl" arg to "search" when going to a document from a search
16 results page. This allows the close book icon (in hierarchy toc) to
17 take you back to the results page if that's where you came from.
18 If you got to the document page somehow other than from a
19 classification or a search (i.e. if "cl" isn't set) then the close
20 book icon is disabled
21
22 Revision 1.4 1999/06/16 02:08:38 sjboddie
23 got queryaction working
24
25 Revision 1.3 1999/03/25 03:06:45 sjboddie
26
27 altered receptionist slightly so it now passes *collectproto to
28 define_internal_macros and define_external_macros - need it
29 for browseaction
30
31 Revision 1.2 1999/03/03 20:26:50 rjmcnab
32
33 Modified stuff.
34
35 Revision 1.1 1999/02/28 22:45:21 rjmcnab
36
37 Initial revision.
38
39 */
40
41
42#include "queryaction.h"
43#include "querytools.h"
44
45queryaction::queryaction () {
46 // this action uses cgi variable "a"
47 cgiarginfo arg_ainfo;
48 arg_ainfo.shortname = "a";
49 arg_ainfo.longname = "action";
50 arg_ainfo.multiplechar = true;
51 arg_ainfo.defaultstatus = cgiarginfo::weak;
52 arg_ainfo.argdefault = "q";
53 arg_ainfo.savedarginfo = cgiarginfo::must;
54 argsinfo.addarginfo (NULL, arg_ainfo);
55
56 // "h"
57 arg_ainfo.shortname = "h";
58 arg_ainfo.longname = "main index";
59 arg_ainfo.multiplechar = true;
60 arg_ainfo.defaultstatus = cgiarginfo::weak;
61 arg_ainfo.argdefault = "";
62 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
63 argsinfo.addarginfo (NULL, arg_ainfo);
64
65 // "j"
66 arg_ainfo.shortname = "j";
67 arg_ainfo.longname = "sub collection index";
68 arg_ainfo.multiplechar = true;
69 arg_ainfo.defaultstatus = cgiarginfo::weak;
70 arg_ainfo.argdefault = "";
71 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
72 argsinfo.addarginfo (NULL, arg_ainfo);
73
74 // "n"
75 arg_ainfo.shortname = "n";
76 arg_ainfo.longname = "language index";
77 arg_ainfo.multiplechar = true;
78 arg_ainfo.defaultstatus = cgiarginfo::weak;
79 arg_ainfo.argdefault = "";
80 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
81 argsinfo.addarginfo (NULL, arg_ainfo);
82
83 // "q"
84 arg_ainfo.shortname = "q";
85 arg_ainfo.longname = "query string";
86 arg_ainfo.multiplechar = true;
87 arg_ainfo.defaultstatus = cgiarginfo::weak;
88 arg_ainfo.argdefault = "";
89 arg_ainfo.savedarginfo = cgiarginfo::must;
90 argsinfo.addarginfo (NULL, arg_ainfo);
91
92 // "t"
93 arg_ainfo.shortname = "t";
94 arg_ainfo.longname = "search type";
95 arg_ainfo.multiplechar = false;
96 arg_ainfo.defaultstatus = cgiarginfo::weak;
97 arg_ainfo.argdefault = "0";
98 arg_ainfo.savedarginfo = cgiarginfo::must;
99 argsinfo.addarginfo (NULL, arg_ainfo);
100
101 // "k"
102 arg_ainfo.shortname = "k";
103 arg_ainfo.longname = "casefolding";
104 arg_ainfo.multiplechar = false;
105 arg_ainfo.defaultstatus = cgiarginfo::weak;
106 arg_ainfo.argdefault = "1";
107 arg_ainfo.savedarginfo = cgiarginfo::must;
108 argsinfo.addarginfo (NULL, arg_ainfo);
109
110 // "s"
111 arg_ainfo.shortname = "s";
112 arg_ainfo.longname = "stemming";
113 arg_ainfo.multiplechar = false;
114 arg_ainfo.defaultstatus = cgiarginfo::weak;
115 arg_ainfo.argdefault ="0";
116 arg_ainfo.savedarginfo = cgiarginfo::must;
117 argsinfo.addarginfo (NULL, arg_ainfo);
118
119 // "m"
120 arg_ainfo.shortname = "m";
121 arg_ainfo.longname = "maximum number of documents";
122 arg_ainfo.multiplechar = true;
123 arg_ainfo.defaultstatus = cgiarginfo::weak;
124 arg_ainfo.argdefault = "50";
125 arg_ainfo.savedarginfo = cgiarginfo::must;
126 argsinfo.addarginfo (NULL, arg_ainfo);
127
128 // "o"
129 arg_ainfo.shortname = "o";
130 arg_ainfo.longname = "hits per page";
131 arg_ainfo.multiplechar = true;
132 arg_ainfo.defaultstatus = cgiarginfo::weak;
133 arg_ainfo.argdefault = "20";
134 arg_ainfo.savedarginfo = cgiarginfo::must;
135 argsinfo.addarginfo (NULL, arg_ainfo);
136
137 // "r"
138 arg_ainfo.shortname = "r";
139 arg_ainfo.longname = "start results from";
140 arg_ainfo.multiplechar = true;
141 arg_ainfo.defaultstatus = cgiarginfo::weak;
142 arg_ainfo.argdefault = "1";
143 arg_ainfo.savedarginfo = cgiarginfo::must;
144 argsinfo.addarginfo (NULL, arg_ainfo);
145}
146
147void queryaction::configure (const text_t &key, const text_tarray &cfgline) {
148 action::configure (key, cfgline);
149}
150
151bool queryaction::init (ostream &logout) {
152 return action::init (logout);
153}
154
155bool queryaction::check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args,
156 ostream &logout) {
157
158 // check t argument
159 int arg_t = args.getintarg("t");
160 if (arg_t != 0 && arg_t != 1) {
161 logout << "Warning: \"t\" argument out of range (" << arg_t << ")\n";
162 args["t"] = argsinfo["t"].argdefault;
163 }
164
165 // check k argument
166 int arg_k = args.getintarg("k");
167 if (arg_k != 0 && arg_k != 1) {
168 logout << "Warning: \"k\" argument out of range (" << arg_k << ")\n";
169 args["k"] = argsinfo["k"].argdefault;
170 }
171
172 // check s argument
173 int arg_s = args.getintarg("s");
174 if (arg_s != 0 && arg_s != 1) {
175 logout << "Warning: \"s\" argument out of range (" << arg_s << ")\n";
176 args["s"] = argsinfo["s"].argdefault;
177 }
178
179 // check m argument
180 int arg_m = args.getintarg("m");
181 if (arg_m < 0) {
182 logout << "Warning: \"m\" argument less than 0 (" << arg_m << ")\n";
183 args["m"] = argsinfo["m"].argdefault;
184 }
185
186 // check o argument
187 int arg_o = args.getintarg("o");
188 if (arg_o < 0) {
189 logout << "Warning: \"o\" argument less than 0 (" << arg_o << ")\n";
190 args["o"] = argsinfo["o"].argdefault;
191 }
192
193 // check r argument
194 int arg_r = args.getintarg("r");
195 if (arg_r < 1) {
196 logout << "Warning: \"r\" argument less than 1 (" << arg_r << ")\n";
197 args["r"] = argsinfo["r"].argdefault;
198 }
199
200 return true;
201}
202
203void queryaction::get_cgihead_info (cgiargsclass &/*args*/, response_t &response,
204 text_t &response_data, ostream &/*logout*/) {
205 response = content;
206 response_data = "text/html";
207}
208
209void queryaction::define_internal_macros (displayclass &/*disp*/, cgiargsclass &/*args*/,
210 recptproto */*collectproto*/, ostream &/*logout*/) {
211
212 // define_internal_macros doesn't set anything for this action. The following
213 // macros are set later though in define_query_macros (they can't be set until
214 // the query has been done).
215
216 // _freqmsg_ the term frequency string
217
218 // _quotedquery_ the part of the query string that was quoted for post-processing
219
220 // _resultline_ the "x documents matched the query" string
221
222 // _prevfirst_ these are used when setting up the links to previous/next
223 // _prevlast_ pages of results (_thisfirst_ and _thislast_ are used to set
224 // _nextfirst_ the 'results x-x for query: xxxx' string in the title bar)
225 // _nextlast_
226 // _thisfirst_
227 // _thislast_
228
229}
230
231// sets the selection box macros _hselection_, _jselection_, and _nselection_.
232// each option will need an _optionxoption_ macro (i.e. an _hselection_ macro
233// with options stx and ptx will need _optionhstx_ and _optionhptx_ macros)
234void queryaction::set_option_macro (const text_t &macroname, text_t current_value,
235 const FilterOption_t &option, displayclass &disp) {
236
237 if (option.validValues.size() < 2) return;
238
239 text_t macrovalue = "<select name=\"" + macroname + "\">\n";
240
241 if (current_value.empty()) current_value = option.defaultValue;
242
243 text_tarray::const_iterator thisvalue = option.validValues.begin();
244 text_tarray::const_iterator endvalue = option.validValues.end();
245
246 while (thisvalue != endvalue) {
247 macrovalue += "<option value=\"" + *thisvalue + "\"";
248 if (*thisvalue == current_value)
249 macrovalue += " selected";
250 macrovalue += ">_option" + macroname + *thisvalue + "_\n";
251 thisvalue ++;
252 }
253 macrovalue += "</select>\n";
254 disp.setmacro (macroname + "selection", "Global", macrovalue);
255}
256
257void queryaction::define_external_macros (displayclass &disp, cgiargsclass &args,
258 recptproto *collectproto, ostream &logout) {
259
260 // define_external_macros sets the following macros:
261
262 // some or all of these may not be required to be set
263 // _hselection_ the selection box for the main part of the index
264 // _jselection_ the selection box for the subcollection part of the index
265 // _nselection_ the selection box for the language part of the index
266
267
268 // can't do anything if collectproto is null (i.e. no collection was specified)
269 if (collectproto == NULL) return;
270
271 comerror_t err;
272 InfoFilterOptionsResponse_t response;
273 InfoFilterOptionsRequest_t request;
274 request.filterName = "QueryFilter";
275
276 collectproto->get_filteroptions (args["c"], request, response, err, logout);
277 if (err == noError) {
278
279 FilterOption_tmap::const_iterator it;
280 FilterOption_tmap::const_iterator end = response.filterOptions.end();
281
282 // _hselection_ (Index)
283 it = response.filterOptions.find ("Index");
284 if (it != end) set_option_macro ("h", args["h"], (*it).second, disp);
285
286 // _jselection_ (Subcollection)
287 it = response.filterOptions.find ("Subcollection");
288 if (it != end) set_option_macro ("j", args["j"], (*it).second, disp);
289
290 // _nselection_ (Language)
291 it = response.filterOptions.find ("Language");
292 if (it != end) set_option_macro ("n", args["n"], (*it).second, disp);
293 }
294}
295
296bool queryaction::do_action (cgiargsclass &args, recptproto *collectproto,
297 displayclass &disp, outconvertclass &outconvert,
298 ostream &textout, ostream &logout) {
299
300 if (collectproto == NULL) {
301 logout << "queryaction::do_action called with NULL collectproto\n";
302 textout << outconvert << disp << "_query:header_\n"
303 << "Error: Attempt to do query without setting collection\n"
304 << "_query:footer_\n";
305 } else {
306
307 text_t quotedstring;
308 FilterResponse_t response;
309
310 // do the query
311 FilterRequest_t request;
312 request.filterResultOptions = FROID | FRmetadata | FRtermFreq;
313 request.fields.push_back ("Title");
314 request.getParents = true;
315 if (!do_query (request, args, collectproto, quotedstring, response, logout))
316 return false;
317
318 // set macros
319 define_query_macros (args, disp, response, quotedstring);
320
321 // output the header
322 textout << outconvert << disp << "_query:header_\n_query:content_";
323
324 // output results
325 ResultDocInfo_tarray::const_iterator this_doc = response.docInfo.begin();
326 ResultDocInfo_tarray::const_iterator end_doc = response.docInfo.end();
327
328 textout << "<table cellspacing=4>\n";
329 while (this_doc != end_doc) {
330
331 text_t link = "<a href=\"_httpdocument_&cl=search&d=" + (*this_doc).OID + "\">";
332
333 text_t title;
334 text_tarray::const_iterator this_title = (*this_doc).metadata[0].values.begin();
335 text_tarray::const_iterator end_title = (*this_doc).metadata[0].values.end();
336 while (this_title != end_title) {
337 if ((this_title + 1) == end_title)
338 title += link + *this_title + "</a>";
339 else
340 title += *this_title + ": ";
341 this_title ++;
342 }
343
344 textout << outconvert << disp << "<tr><td valign=top nowrap>" << link
345 << "_icontext_</a></td><td>" << title << "</td></tr>\n";
346
347 this_doc ++;
348 }
349 textout << "</table>\n";
350
351 // output the footer
352 textout << outconvert << disp << "_query:footer_";
353 }
354 return true;
355}
356
357// set_query_macros sets the macros that couldn't be set until the
358// query had been done. Those macros are _freqmsg_, _quotedquery_,
359// _resultline_, _nextfirst_, _nextlast_, _prevfirst_, _prevlast_,
360// _thisfirst_, and _thislast_
361void queryaction::define_query_macros (cgiargsclass &args, displayclass &disp,
362 const FilterResponse_t &response,
363 const text_t &quotedstring) {
364
365 int numdocs = response.numDocs;
366 int arg_m = args.getintarg("m");
367 if (numdocs > arg_m)
368 numdocs = arg_m;
369
370 // set up _freqmsg_ and _quotedquery_ macros
371 text_t freqmsg = "_textfreqmsg1_";
372 TermInfo_tarray::const_iterator this_term = response.termInfo.begin();
373 TermInfo_tarray::const_iterator end_term = response.termInfo.end();
374 while (this_term != end_term) {
375 freqmsg += (*this_term).term + ": " + (*this_term).freq;
376 if ((this_term + 1) != end_term)
377 freqmsg += ", ";
378 this_term ++;
379 }
380
381 disp.setmacro ("quotedquery", "query", quotedstring);
382 disp.setmacro ("freqmsg", "query", freqmsg);
383
384
385 // set up _resultline_ macro
386 text_t resline;
387
388 // can't use isApprox here as it will be false as long
389 // as numDocs < MAXDOCS (currently 200). If arg_m is less
390 // than MAXDOCS numDocs can be greater than arg_m while
391 // isApprox is false.
392 if (response.numDocs >= numdocs) resline = "_textmorethan_";
393 if (numdocs == 0) resline = "_textnodocs_";
394 else if (numdocs == 1) resline += "_text1doc_";
395 else resline += text_t(numdocs) + "_textlotsdocs_";
396
397 disp.setmacro("resultline", "query", resline);
398
399
400 int firstdoc = args.getintarg("r");
401 int hitsperpage = args.getintarg("o");
402
403 // set up _thisfirst_ and _thislast_ macros
404 disp.setmacro ("thisfirst", "query", firstdoc);
405 int thislast = firstdoc + (hitsperpage - 1);
406 if (thislast > numdocs) thislast = numdocs;
407 disp.setmacro ("thislast", "query", thislast);
408
409 // set up _prevfirst_ and _prevlast_ macros
410 if (firstdoc > 1) {
411 disp.setmacro ("prevlast", "query", firstdoc - 1);
412 int prevfirst = firstdoc - hitsperpage;
413 if (prevfirst < 1) prevfirst = 1;
414 disp.setmacro ("prevfirst", "query", prevfirst);
415 }
416
417 // set up _nextfirst_ and _nextlast_ macros
418 if (thislast < numdocs) {
419 disp.setmacro ("nextfirst", "query", thislast + 1);
420 int nextlast = thislast + hitsperpage;
421 if (nextlast > numdocs) nextlast = numdocs;
422 disp.setmacro ("nextlast", "query", nextlast);
423 }
424}
425
426
427
Note: See TracBrowser for help on using the repository browser.