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

Last change on this file since 472 was 472, checked in by sjboddie, 25 years ago

changed FilterRequest_t::docSet into an array

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