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

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

changed isApprox

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