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

Last change on this file since 493 was 493, checked in by rjmcnab, 25 years ago

A few changes to get compiling on AIX.

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