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

Last change on this file since 2212 was 2212, checked in by sjboddie, 23 years ago

Fixed a bug that was causing the local library server to attempt to write
files to gsdlhome (i.e. the cd-rom drive if served from a cd) under certain
circumstances.

  • Property svn:keywords set to Author Date Id Revision
File size: 8.9 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 *********************************************************************/
25
26#include "browsefilter.h"
27#include "fileutil.h"
28#include "gsdltools.h"
29
30
31browsefilterclass::browsefilterclass () {
32 gdbmptr = NULL;
33
34 // -- onePerQuery StartResults integer
35 FilterOption_t filtopt;
36 filtopt.name = "StartResults";
37 filtopt.type = FilterOption_t::integert;
38 filtopt.repeatable = FilterOption_t::onePerQuery;
39 filtopt.defaultValue = "1";
40 filtopt.validValues.push_back("1");
41 filtopt.validValues.push_back("10000");
42 filterOptions["StartResults"] = filtopt;
43
44 // -- onePerQuery EndResults integer
45 filtopt.clear();
46 filtopt.name = "EndResults";
47 filtopt.type = FilterOption_t::integert;
48 filtopt.repeatable = FilterOption_t::onePerQuery;
49 filtopt.defaultValue = "-1";
50 filtopt.validValues.push_back("-1");
51 filtopt.validValues.push_back("10000");
52 filterOptions["EndResults"] = filtopt;
53
54 // -- onePerQuery ParentNode string ("" will return the browsing available)
55 filtopt.clear();
56 filtopt.name = "ParentNode";
57 filtopt.type = FilterOption_t::stringt;
58 filtopt.repeatable = FilterOption_t::onePerQuery;
59 filtopt.defaultValue = "";
60 filterOptions["ParentNode"] = filtopt;
61}
62
63browsefilterclass::~browsefilterclass () {
64}
65
66bool browsefilterclass::init (ostream &logout) {
67 outconvertclass text_t2ascii;
68
69 if (!filterclass::init(logout)) return false;
70
71 // get the filename for the database and make sure it exists
72 gdbm_filename = filename_cat(gdbmhome, "collect", collection, "index", "text", collection);
73
74 if (littleEndian()) gdbm_filename += ".ldb";
75 else gdbm_filename += ".bdb";
76
77 if (!file_exists(gdbm_filename)) {
78 logout << text_t2ascii
79 << "warning: gdbm database \"" //****
80 << gdbm_filename << "\" does not exist\n\n";
81 // return false; //****
82 }
83
84 return true;
85}
86
87void browsefilterclass::filter (const FilterRequest_t &request,
88 FilterResponse_t &response,
89 comerror_t &err, ostream &logout) {
90 int numDocs = 0;
91 outconvertclass text_t2ascii;
92
93 response.clear ();
94 err = noError;
95 if (gdbmptr == NULL) {
96 // most likely a configuration problem
97 logout << text_t2ascii
98 << "configuration error: browsefilter contains a null gdbmclass\n\n";
99 err = configurationError;
100 return;
101 }
102
103 // open the database
104 gdbmptr->setlogout(&logout);
105 if (!gdbmptr->opendatabase (gdbm_filename, GDBM_READER, 100, false)) {
106 // most likely a system problem (we have already checked that the
107 // gdbm database exists)
108 logout << text_t2ascii
109 << "system problem: open on gdbm database \""
110 << gdbm_filename << "\" failed\n\n";
111 err = systemProblem;
112 return;
113 }
114
115 // get the browse parameters
116 int startresults = filterOptions["StartResults"].defaultValue.getint();
117 int endresults = filterOptions["EndResults"].defaultValue.getint();
118 text_t parentnode = filterOptions["ParentNode"].defaultValue;
119 OptionValue_tarray::const_iterator options_here = request.filterOptions.begin();
120 OptionValue_tarray::const_iterator options_end = request.filterOptions.end();
121 while (options_here != options_end) {
122 if ((*options_here).name == "StartResults")
123 startresults = (*options_here).value.getint();
124 else if ((*options_here).name == "EndResults")
125 endresults = (*options_here).value.getint();
126 else if ((*options_here).name == "ParentNode")
127 parentnode = (*options_here).value;
128 else {
129 logout << text_t2ascii
130 << "warning: unknown browsefilter option \""
131 << (*options_here).name
132 << "\" ignored.\n\n";
133 }
134
135 options_here++;
136 }
137
138 infodbclass info;
139
140 // translate any ".fc", ".pr" etc. stuff in the parentnode
141 parentnode = gdbmptr->translate_OID (parentnode, info);
142
143 // adjust topmost browsing node
144 if (parentnode.empty()) parentnode = "browse";
145
146 // get the node
147 if ((request.filterResultOptions & FROID) ||
148 (request.filterResultOptions & FRmetadata)) {
149 if (!gdbmptr->getinfo(parentnode, info)) {
150 // didn't find the node
151 logout << text_t2ascii
152 << "warning: lookup for node \"" << parentnode
153 << "\" failed for browsefilter.\n\n";
154 } else {
155 // found the node
156
157 // replace " with the parent node name and split the contains string
158 // into the result set
159 text_tarray resultset;
160 text_t tmptext;
161 text_t &contains = info["contains"];
162 text_t::iterator contains_here = contains.begin();
163 text_t::iterator contains_end = contains.end();
164 while (contains_here != contains_end) {
165 if (*contains_here == '"') tmptext += parentnode;
166 else if (*contains_here == ';') {
167 if (!tmptext.empty()) resultset.push_back (tmptext);
168 tmptext.clear();
169 } else tmptext.push_back(*contains_here);
170
171 contains_here++;
172 }
173 // insert the last result in the set
174 if (!tmptext.empty()) resultset.push_back (tmptext);
175
176 text_tarray offset_resultset;
177 text_t &md_type = info["mdtype"];
178 if (!md_type.empty())
179 {
180 text_t &md_offset = info["mdoffset"];
181 if (!md_offset.empty())
182 {
183 text_t offsettext;
184
185 text_t::iterator offset_here = md_offset.begin();
186 text_t::iterator offset_end = md_offset.end();
187 while (offset_here != offset_end)
188 {
189 if (*offset_here == ';')
190 {
191 if (offsettext.empty())
192 {
193 offset_resultset.push_back ("0");
194 }
195 else
196 {
197 offset_resultset.push_back (offsettext);
198 }
199 offsettext.clear();
200 }
201 else
202 {
203 offsettext.push_back(*offset_here);
204 }
205
206 offset_here++;
207 }
208 // insert the last result in the set
209 if (offsettext.empty())
210 {
211 offset_resultset.push_back ("0");
212 }
213 else
214 {
215 offset_resultset.push_back (offsettext);
216 }
217 }
218 else
219 {
220 // add 0 offset for each 'contains' entry
221 text_tarray::iterator result_here = resultset.begin();
222 text_tarray::iterator result_end = resultset.end();
223 while (result_here != result_end) {
224 offset_resultset.push_back("0");
225 result_here++;
226 }
227 }
228
229 // do an intersection with the input set
230 if (!request.docSet.empty()) {
231
232 text_tarray intersect_resultset;
233 text_tarray intersect_offset_resultset;
234
235 text_tarray::const_iterator resultset_here = resultset.begin();
236 text_tarray::const_iterator resultset_end = resultset.end();
237 text_tarray::const_iterator offset_resultset_here = offset_resultset.begin();
238
239 while (resultset_here != resultset_end) {
240 if (in_set (request.docSet, *resultset_here))
241 {
242 intersect_resultset.push_back (*resultset_here);
243 intersect_offset_resultset.push_back (*offset_resultset_here);
244 }
245 resultset_here ++;
246 offset_resultset_here ++;
247 }
248 resultset = intersect_resultset;
249 offset_resultset = intersect_offset_resultset;
250 }
251 }
252 else
253 {
254 // do an intersection with the input set
255 if (!request.docSet.empty()) {
256 intersect (resultset, request.docSet);
257 }
258
259 // add 0 offset for each 'contains' entry
260 text_tarray::iterator result_here = resultset.begin();
261 text_tarray::iterator result_end = resultset.end();
262 while (result_here != result_end) {
263 offset_resultset.push_back("0");
264 result_here++;
265 }
266 }
267
268 // create the response
269 numDocs = resultset.size();
270 int resultnum = 1;
271 ResultDocInfo_t resultdoc;
272 text_tarray::iterator result_here = resultset.begin();
273 text_tarray::iterator result_end = resultset.end();
274 text_tarray::iterator offset_result_here = offset_resultset.begin();
275
276 while (result_here != result_end) {
277 // if endresults is -1 get all results
278 if ((endresults != -1) && (resultnum > endresults)) break;
279 if (resultnum >= startresults) {
280 resultdoc.OID = (*result_here);
281 if (!md_type.empty())
282 {
283 resultdoc.classifier_metadata_type = md_type;
284 resultdoc.classifier_metadata_offset = offset_result_here->getint();
285 }
286 response.docInfo.push_back(resultdoc);
287 }
288
289 resultnum++;
290 result_here++;
291 if (!md_type.empty()) offset_result_here++;
292 }
293 }
294 }
295
296 response.numDocs = numDocs;
297 response.isApprox = Exact;
298}
Note: See TracBrowser for help on using the repository browser.