source: branches/New_Config_Format-branch/gsdl/src/colservr/browsefilter.cpp@ 1279

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

merged changes to trunk into New_Config_Format branch

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