source: trunk/gsdl/src/colservr/filter.cpp@ 1285

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

Removed CVS logging information from source files

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1/**********************************************************************
2 *
3 * filter.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 "filter.h"
27#include "fileutil.h"
28#include <assert.h>
29
30
31// default constructor does nothing
32filterclass::filterclass () {
33}
34
35// default destructor does nothing
36filterclass::~filterclass () {
37}
38
39// configure should be called once for each configuration line
40// default configures the default filter options
41void filterclass::configure (const text_t &key, const text_tarray &cfgline) {
42 if (cfgline.size() >= 1) {
43 const text_t &value = cfgline[0];
44
45 if (key == "collection") collection = value;
46 else if (key == "collectdir") collectdir = value;
47 else if (key == "gsdlhome") gsdlhome = value;
48 else if ((key == "filteroptdefault") && (cfgline.size() == 2)) {
49 // see if this filter has an option with this name
50 FilterOption_tmap::iterator thisfilteroption =
51 filterOptions.find(cfgline[0]);
52 if (thisfilteroption != filterOptions.end())
53 (*thisfilteroption).second.defaultValue = cfgline[1];
54 }
55 }
56}
57
58// init should be called after all the configuration is done but
59// before any other methods are called
60// default checks all the filter option defaults
61bool filterclass::init (ostream &/*logout*/) {
62 // check all the filter defaults
63 FilterOption_tmap::iterator filteroption_here = filterOptions.begin();
64 FilterOption_tmap::iterator filteroption_end = filterOptions.end();
65 while (filteroption_here != filteroption_end) {
66 (*filteroption_here).second.check_defaultValue ();
67
68 filteroption_here++;
69 }
70
71 // get the collection directory name
72 if (collectdir.empty()) {
73 collectdir = filename_cat (gsdlhome, "collect", collection);
74 }
75
76 return true;
77}
78
79// returns the name of this filter
80// default returns "NullFilter"
81text_t filterclass::get_filter_name () {
82 return "NullFilter";
83}
84
85// returns the current filter options
86void filterclass::get_filteroptions (InfoFilterOptionsResponse_t &response,
87 comerror_t &err, ostream &/*logout*/) {
88 response.clear();
89 response.filterOptions = filterOptions;
90 err = noError;
91}
92
93// default returns nothing
94void filterclass::filter (const FilterRequest_t &request,
95 FilterResponse_t &response,
96 comerror_t &err, ostream &/*logout*/) {
97 ResultDocInfo_t resultdoc;
98
99 response.clear();
100
101 if ((request.filterResultOptions & FROID) ||
102 (request.filterResultOptions & FRmetadata)) {
103 // copy the OIDs from the request to the response
104 text_tarray::const_iterator here = request.docSet.begin();
105 text_tarray::const_iterator end = request.docSet.end();
106 while (here != end) {
107 resultdoc.OID = (*here);
108 response.docInfo.push_back(resultdoc);
109
110 here++;
111 }
112 }
113
114 response.numDocs = response.docInfo.size();
115 response.isApprox = Exact;
116 err = noError;
117}
118
119
120bool operator==(const filterptr &x, const filterptr &y) {
121 return (x.f == y.f);
122}
123
124bool operator<(const filterptr &x, const filterptr &y) {
125 return (x.f < y.f);
126}
127
128
129// thefilter remains the property of the calling code but
130// should not be deleted until it is removed from this list.
131void filtermapclass::addfilter (filterclass *thefilter) {
132 // can't add a null filter
133 assert (thefilter != NULL);
134 if (thefilter == NULL) return;
135
136 // can't add an filter with no name
137 assert (!(thefilter->get_filter_name()).empty());
138 if ((thefilter->get_filter_name()).empty()) return;
139
140 filterptr fptr;
141 fptr.f = thefilter;
142 filterptrs[thefilter->get_filter_name()] = fptr;
143}
144
145// getfilter will return NULL if the filter could not be found
146filterclass *filtermapclass::getfilter (const text_t &key) {
147 // can't find an filter with no name
148 assert (!key.empty());
149 if (key.empty()) return NULL;
150
151 iterator here = filterptrs.find (key);
152 if (here == filterptrs.end()) return NULL;
153
154 return (*here).second.f;
155}
156
157
158
159
160// some useful functions for dealing with document sets
161
162// returns -1 if t1 is a child of t2
163// returns 0 if t1 and t2 are not parent-child related
164// returns 1 if t1 is a parent of t2
165int child_compare (const text_t &t1, const text_t &t2) {
166 text_t::const_iterator t1_here = t1.begin();
167 text_t::const_iterator t1_end = t1.end();
168 text_t::const_iterator t2_here = t2.begin();
169 text_t::const_iterator t2_end = t2.end();
170
171 while ((t1_here != t1_end) && (t2_here != t2_end)) {
172 if (*t1_here != *t2_here) return 0; // unrelated
173 t1_here++;
174 t2_here++;
175 }
176
177 if ((t1_here == t1_end) && (t2_here == t2_end)) return 0; // equal
178 if (t1_here != t1_end) {
179 if (*t1_here == '.') return -1; // t1 is child
180 else return 0; // unrelated
181 }
182
183 if (t2_here != t2_end) {
184 if (*t2_here == '.') return 1; // t2 is child
185 else return 0; // unrelated
186 }
187
188 return 0; // shouldn't get here...
189}
190
191// intersect places the result in set1
192void intersect (text_tset &set1, const text_tset &set2) {
193 text_tset resultset;
194 int childcomp = 0;
195
196 text_tset::const_iterator set1_here = set1.begin();
197 text_tset::const_iterator set1_end = set1.end();
198 text_tset::const_iterator set2_here = set2.begin();
199 text_tset::const_iterator set2_end = set2.end();
200 while ((set1_here != set1_end) && (set2_here != set2_end)) {
201 if (*set1_here == *set2_here) {
202 // equal
203 resultset.insert (*set1_here);
204 set1_here++;
205 set2_here++;
206
207 } else if ((childcomp=child_compare(*set1_here, *set2_here)) != 0) {
208 if (childcomp < 0) {
209 // set1_here is child
210 resultset.insert (*set1_here);
211 set1_here++;
212 } else {
213 // set2_here is child
214 resultset.insert (*set2_here);
215 set2_here++;
216 }
217
218 } else if (*set1_here < *set2_here) {
219 // set1 is less
220 set1_here++;
221
222 } else {
223 // set2 is less
224 set2_here++;
225 }
226 }
227
228 set1 = resultset;
229}
230
231void intersect (text_tarray &set1, const text_tset &set2) {
232 text_tarray resultset;
233
234 text_tarray::const_iterator set1_here = set1.begin();
235 text_tarray::const_iterator set1_end = set1.end();
236
237 while (set1_here != set1_end) {
238 if (in_set (set2, *set1_here))
239 resultset.push_back (*set1_here);
240 set1_here ++;
241 }
242 set1 = resultset;
243}
244
245void intersect (text_tarray &set1, const text_tarray &set2) {
246 text_tarray resultset;
247
248 text_tarray::const_iterator set1_here = set1.begin();
249 text_tarray::const_iterator set1_end = set1.end();
250
251 while (set1_here != set1_end) {
252 if (in_set (set2, *set1_here))
253 resultset.push_back (*set1_here);
254 set1_here ++;
255 }
256 set1 = resultset;
257}
258
259// tests to see if el is in set
260bool in_set (const text_tset &set1, const text_t &el) {
261 text_t::const_iterator here = el.begin();
262 text_t::const_iterator end = el.begin();
263 text_t tryel, tryel_add;
264 bool first = true;
265
266 // the element is in the set if any of its parents are
267 // in the set
268 do {
269 // get next possible element to try
270 here = getdelimitstr (here, end, '.', tryel_add);
271 if (!first) tryel += ".";
272 first = false;
273 tryel += tryel_add;
274
275 // see if this element is in the set
276 if (set1.find(tryel) != set1.end()) return true;
277 } while (here != end);
278
279 return false;
280}
281
282bool in_set (const text_tarray &set1, const text_t &el) {
283 text_t::const_iterator here = el.begin();
284 text_t::const_iterator end = el.begin();
285 text_t tryel, tryel_add;
286 bool first = true;
287
288 // the element is in the set if any of its parents are
289 // in the set
290 do {
291 // get next possible element to try
292 here = getdelimitstr (here, end, '.', tryel_add);
293 if (!first) tryel += ".";
294 first = false;
295 tryel += tryel_add;
296
297 // see if this element is in the set
298 text_tarray::const_iterator here = set1.begin();
299 text_tarray::const_iterator end = set1.end();
300 while (here != end) {
301 if (*here == tryel) break;
302 here ++;
303 }
304 if (here != end) return true;
305 } while (here != end);
306
307 return false;
308}
Note: See TracBrowser for help on using the repository browser.