source: trunk/gsdl/src/colservr/browsefilter.cpp@ 990

Last change on this file since 990 was 990, checked in by sjboddie, 24 years ago

tidied up endianness and fastcgi

  • Property svn:keywords set to Author Date Id Revision
File size: 9.5 KB
Line 
1/**********************************************************************
2 *
3 * browsefilter.cpp --
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * $Id: browsefilter.cpp 990 2000-02-29 01:35:56Z sjboddie $
25 *
26 *********************************************************************/
27
28/*
29 $Log$
30 Revision 1.10 2000/02/29 01:35:56 sjboddie
31 tidied up endianness and fastcgi
32
33 Revision 1.9 1999/12/13 02:55:49 davidb
34 Support for docs/sections with more than one metavalue for a metadata name
35
36 Revision 1.8 1999/10/19 03:23:39 davidb
37 Collection building support through web pages
38 and internal and external link handling for collection documents
39
40 Revision 1.7 1999/09/07 04:57:20 sjboddie
41 added gpl notice
42
43 Revision 1.6 1999/08/31 22:33:21 rjmcnab
44 small update.
45
46 Revision 1.5 1999/07/16 03:42:23 sjboddie
47 changed isApprox
48
49 Revision 1.4 1999/05/10 03:43:47 sjboddie
50 lots of changes to lots of files - getting document action going
51
52 Revision 1.3 1999/04/30 02:00:45 sjboddie
53 lots of stuff to do with getting documentaction working
54
55 Revision 1.2 1999/04/19 23:56:05 rjmcnab
56 Finished the gdbm metadata stuff
57
58 Revision 1.1 1999/04/06 22:22:08 rjmcnab
59 Initial revision.
60
61 */
62
63
64#include "browsefilter.h"
65#include "fileutil.h"
66#include "gsdltools.h"
67
68
69browsefilterclass::browsefilterclass () {
70 gdbmptr = NULL;
71
72 // -- onePerQuery StartResults integer
73 FilterOption_t filtopt;
74 filtopt.name = "StartResults";
75 filtopt.type = FilterOption_t::integert;
76 filtopt.repeatable = FilterOption_t::onePerQuery;
77 filtopt.defaultValue = "1";
78 filtopt.validValues.push_back("1");
79 filtopt.validValues.push_back("10000");
80 filterOptions["StartResults"] = filtopt;
81
82 // -- onePerQuery EndResults integer
83 filtopt.clear();
84 filtopt.name = "EndResults";
85 filtopt.type = FilterOption_t::integert;
86 filtopt.repeatable = FilterOption_t::onePerQuery;
87 filtopt.defaultValue = "10000";
88 filtopt.validValues.push_back("1");
89 filtopt.validValues.push_back("10000");
90 filterOptions["EndResults"] = filtopt;
91
92 // -- onePerQuery ParentNode string ("" will return the browsing available)
93 filtopt.clear();
94 filtopt.name = "ParentNode";
95 filtopt.type = FilterOption_t::stringt;
96 filtopt.repeatable = FilterOption_t::onePerQuery;
97 filtopt.defaultValue = "";
98 filterOptions["ParentNode"] = filtopt;
99}
100
101browsefilterclass::~browsefilterclass () {
102}
103
104bool browsefilterclass::init (ostream &logout) {
105 outconvertclass text_t2ascii;
106
107 if (!filterclass::init(logout)) return false;
108
109 // get the filename for the database and make sure it exists
110 gdbm_filename = filename_cat(collectdir,"index","text",collection);
111
112 if (littleEndian()) gdbm_filename += ".ldb";
113 else gdbm_filename += ".bdb";
114
115 if (!file_exists(gdbm_filename)) {
116 logout << text_t2ascii
117 << "warning: gdbm database \"" //****
118 << gdbm_filename << "\" does not exist\n\n";
119 // return false; //****
120 }
121
122 return true;
123}
124
125void browsefilterclass::filter (const FilterRequest_t &request,
126 FilterResponse_t &response,
127 comerror_t &err, ostream &logout) {
128 int numDocs = 0;
129 outconvertclass text_t2ascii;
130
131 response.clear ();
132 err = noError;
133 if (gdbmptr == NULL) {
134 // most likely a configuration problem
135 logout << text_t2ascii
136 << "configuration error: browsefilter contains a null gdbmclass\n\n";
137 err = configurationError;
138 return;
139 }
140
141 // open the database
142 gdbmptr->setlogout(&logout);
143 if (!gdbmptr->opendatabase (gdbm_filename, GDBM_READER, 100, false)) {
144 // most likely a system problem (we have already checked that the
145 // gdbm database exists)
146 logout << text_t2ascii
147 << "system problem: open on gdbm database \""
148 << gdbm_filename << "\" failed\n\n";
149 err = systemProblem;
150 return;
151 }
152
153 // get the browse parameters
154 int startresults = filterOptions["StartResults"].defaultValue.getint();
155 int endresults = filterOptions["EndResults"].defaultValue.getint();
156 text_t parentnode = filterOptions["ParentNode"].defaultValue;
157 OptionValue_tarray::const_iterator options_here = request.filterOptions.begin();
158 OptionValue_tarray::const_iterator options_end = request.filterOptions.end();
159 while (options_here != options_end) {
160 if ((*options_here).name == "StartResults")
161 startresults = (*options_here).value.getint();
162 else if ((*options_here).name == "EndResults")
163 endresults = (*options_here).value.getint();
164 else if ((*options_here).name == "ParentNode")
165 parentnode = (*options_here).value;
166 else {
167 logout << text_t2ascii
168 << "warning: unknown browsefilter option \""
169 << (*options_here).name
170 << "\" ignored.\n\n";
171 }
172
173 options_here++;
174 }
175
176 infodbclass info;
177
178 // translate any ".fc", ".pr" etc. stuff in the parentnode
179 parentnode = gdbmptr->translate_OID (parentnode, info);
180
181 // adjust topmost browsing node
182 if (parentnode.empty()) parentnode = "browse";
183
184 // get the node
185 if ((request.filterResultOptions & FROID) ||
186 (request.filterResultOptions & FRmetadata)) {
187 if (!gdbmptr->getinfo(parentnode, info)) {
188 // didn't find the node
189 logout << text_t2ascii
190 << "warning: lookup for node \"" << parentnode
191 << "\" failed for browsefilter.\n\n";
192 } else {
193 // found the node
194
195 // replace " with the parent node name and split the contains string
196 // into the result set
197 text_tarray resultset;
198 text_t tmptext;
199 text_t &contains = info["contains"];
200 text_t::iterator contains_here = contains.begin();
201 text_t::iterator contains_end = contains.end();
202 while (contains_here != contains_end) {
203 if (*contains_here == '"') tmptext += parentnode;
204 else if (*contains_here == ';') {
205 if (!tmptext.empty()) resultset.push_back (tmptext);
206 tmptext.clear();
207 } else tmptext.push_back(*contains_here);
208
209 contains_here++;
210 }
211 // insert the last result in the set
212 if (!tmptext.empty()) resultset.push_back (tmptext);
213
214 text_tarray offset_resultset;
215 text_t &md_type = info["mdtype"];
216 if (!md_type.empty())
217 {
218 text_t &md_offset = info["mdoffset"];
219 if (!md_offset.empty())
220 {
221 text_t offsettext;
222
223 text_t::iterator offset_here = md_offset.begin();
224 text_t::iterator offset_end = md_offset.end();
225 while (offset_here != offset_end)
226 {
227 if (*offset_here == ';')
228 {
229 if (offsettext.empty())
230 {
231 offset_resultset.push_back ("0");
232 }
233 else
234 {
235 offset_resultset.push_back (offsettext);
236 }
237 offsettext.clear();
238 }
239 else
240 {
241 offsettext.push_back(*offset_here);
242 }
243
244 offset_here++;
245 }
246 // insert the last result in the set
247 if (!offsettext.empty()) offset_resultset.push_back (offsettext);
248 }
249 else
250 {
251 // add 0 offset for each 'contains' entry
252 text_tarray::iterator result_here = resultset.begin();
253 text_tarray::iterator result_end = resultset.end();
254 while (result_here != result_end) {
255 offset_resultset.push_back("0");
256 result_here++;
257 }
258 }
259
260 // do an intersection with the input set
261 if (!request.docSet.empty()) {
262
263 text_tarray intersect_resultset;
264 text_tarray intersect_offset_resultset;
265
266 text_tarray::const_iterator resultset_here = resultset.begin();
267 text_tarray::const_iterator resultset_end = resultset.end();
268 text_tarray::const_iterator offset_resultset_here = offset_resultset.begin();
269
270 while (resultset_here != resultset_end) {
271 if (in_set (request.docSet, *resultset_here))
272 {
273 intersect_resultset.push_back (*resultset_here);
274 intersect_offset_resultset.push_back (*offset_resultset_here);
275 }
276 resultset_here ++;
277 offset_resultset_here ++;
278 }
279 resultset = intersect_resultset;
280 offset_resultset = intersect_offset_resultset;
281 }
282 }
283 else
284 {
285 // do an intersection with the input set
286 if (!request.docSet.empty()) {
287 intersect (resultset, request.docSet);
288 }
289 }
290
291 // create the response
292 numDocs = resultset.size();
293 int resultnum = 1;
294 ResultDocInfo_t resultdoc;
295 text_tarray::iterator result_here = resultset.begin();
296 text_tarray::iterator result_end = resultset.end();
297 text_tarray::iterator offset_result_here = offset_resultset.begin();
298
299 while (result_here != result_end) {
300 if (resultnum > endresults) break;
301 if (resultnum >= startresults) {
302 resultdoc.OID = (*result_here);
303 if (!md_type.empty())
304 {
305 resultdoc.classifier_metadata_type = md_type;
306 resultdoc.classifier_metadata_offset = offset_result_here->getint();
307 }
308 response.docInfo.push_back(resultdoc);
309 }
310
311 resultnum++;
312 result_here++;
313 if (!md_type.empty()) offset_result_here++;
314 }
315 }
316 }
317
318 response.numDocs = numDocs;
319 response.isApprox = Exact;
320}
Note: See TracBrowser for help on using the repository browser.