source: trunk/gsdl/src/recpt/OIDtools.cpp@ 649

Last change on this file since 649 was 649, checked in by sjboddie, 25 years ago
  • metadata now returns mp rather than array
  • redesigned browsing support (although it's not finished so

won't currently work ;-)

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 10.6 KB
Line 
1/**********************************************************************
2 *
3 * OIDtools.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 * $Id: OIDtools.cpp 649 1999-10-10 08:14:12Z sjboddie $
25 *
26 *********************************************************************/
27
28/*
29 $Log$
30 Revision 1.17 1999/10/10 08:14:02 sjboddie
31 - metadata now returns mp rather than array
32 - redesigned browsing support (although it's not finished so
33 won't currently work ;-)
34
35 Revision 1.16 1999/09/07 04:56:51 sjboddie
36 added GPL notice
37
38 Revision 1.15 1999/09/02 00:22:04 rjmcnab
39 added extra check in get_info
40
41 Revision 1.14 1999/08/25 04:45:25 sjboddie
42 changed FilterRequest_t::docSet into an array
43
44 Revision 1.13 1999/08/10 22:44:06 sjboddie
45 altered the get_contents function so it's now passed metadata
46 rather than having it hard-coded
47
48 Revision 1.12 1999/07/30 02:26:44 sjboddie
49 added overloaded get_info function for getting info on multiple OIDs
50
51 Revision 1.11 1999/07/20 02:59:03 sjboddie
52 get_children now takes a getParents argument
53
54 Revision 1.10 1999/07/07 05:47:41 sjboddie
55 changed around the way browsetools works
56
57 Revision 1.9 1999/06/16 23:51:53 sjboddie
58 added a strip_suffix function
59
60 Revision 1.8 1999/06/16 03:11:25 sjboddie
61 get_info() now takes a getParents argument
62
63 Revision 1.7 1999/06/16 02:05:23 sjboddie
64 just changed a comment that was confusing me
65
66 Revision 1.6 1999/05/10 03:40:25 sjboddie
67 lots of changes - slowly getting document action sorted out
68
69 Revision 1.5 1999/04/30 01:59:37 sjboddie
70 lots of stuff - getting documentaction working (documentaction replaces
71 old browseaction)
72
73 Revision 1.4 1999/03/29 02:14:25 sjboddie
74
75 More changes to browseaction
76
77 Revision 1.3 1999/03/25 03:13:42 sjboddie
78
79 More library functions for dealing with OIDs. Many of them just
80 return dummy data at present
81
82 Revision 1.2 1999/03/05 03:53:53 sjboddie
83
84 fixed some bugs
85
86 Revision 1.1 1999/03/04 22:38:20 sjboddie
87
88 Added subjectbrowseaction. - Doesn't do anything yet.
89
90 */
91
92#include "OIDtools.h"
93
94
95// returns (in top) the top level of OID (i.e. everything
96// up until the first dot)
97void get_top (const text_t &OID, text_t &top) {
98
99 top.clear();
100 if (OID.empty()) return;
101
102 text_t::const_iterator begin = OID.begin();
103 text_t::const_iterator end = OID.end();
104
105 top.appendrange (begin, findchar(begin, end, '.'));
106}
107
108
109// checks if OID is top level (i.e. contains no dots)
110bool is_top (const text_t &OID) {
111
112 if (OID.empty()) return true;
113
114 text_t::const_iterator here = OID.begin();
115 text_t::const_iterator end = OID.end();
116 here = findchar (here, end, '.');
117
118 if (here == end) return true;
119 return false;
120}
121
122
123// get_parents_array loads the parents array with all the parents of the
124// document or classification specified by OID (not including OID itself)
125void get_parents_array (const text_t &OID, text_tarray &parents) {
126
127 parents.erase (parents.begin(), parents.end());
128
129 text_t::const_iterator here = OID.begin ();
130 text_t::const_iterator end = OID.end ();
131 text_t thisparent;
132
133 while (here != end) {
134 if (*here == '.') parents.push_back(thisparent);
135 thisparent.push_back(*here);
136 here ++;
137 }
138}
139
140
141// get_info does a protocol call and returns (in response) the metadata
142// associated with OID. Metadata should be loaded with whatever
143// metadata fields are to be requested.
144
145bool get_info (const text_t &OID, const text_t &collection,
146 const text_tset &metadata, bool getParents,
147 recptproto *collectproto, FilterResponse_t &response,
148 ostream &logout) {
149
150 response.clear();
151
152 comerror_t err;
153 FilterRequest_t request;
154
155 request.filterName = "NullFilter";
156 request.filterResultOptions = FRmetadata;
157 request.getParents = getParents;
158 request.fields = metadata;
159 request.docSet.push_back (OID);
160
161 collectproto->filter (collection, request, response, err, logout);
162 if (err != noError) {
163 outconvertclass text_t2ascii;
164 logout << text_t2ascii
165 << "Error: call to filter failed for " << OID
166 << " in OIDtools::get_info ("
167 << get_comerror_string (err) << ")\n";
168 return false;
169 }
170
171 return true;
172}
173
174bool get_info (const text_tarray &OIDs, const text_t &collection,
175 const text_tset &metadata, bool getParents,
176 recptproto *collectproto, FilterResponse_t &response,
177 ostream &logout) {
178
179 response.clear();
180 if (OIDs.empty()) return true;
181
182 comerror_t err;
183 FilterRequest_t request;
184
185 request.filterName = "NullFilter";
186 request.filterResultOptions = FRmetadata;
187 request.getParents = getParents;
188 request.fields = metadata;
189
190 request.docSet = OIDs;
191
192 collectproto->filter (collection, request, response, err, logout);
193 if (err != noError) {
194 outconvertclass text_t2ascii;
195 logout << text_t2ascii
196 << "Error: call to filter failed in OIDtools::get_info ("
197 << get_comerror_string (err) << ")\n";
198 return false;
199 }
200
201 return true;
202}
203
204// has_children returns true if OID has children
205bool has_children (const text_t &OID, const text_t &collection,
206 recptproto *collectproto, ostream &logout) {
207
208 FilterResponse_t response;
209 text_tset metadata;
210 metadata.insert ("haschildren");
211
212 if (get_info (OID, collection, metadata, false, collectproto, response, logout)) {
213 if (response.docInfo[0].metadata["haschildren"].values[0] == "1")
214 return true;
215 }
216 return false;
217}
218
219
220// get_children does a protocol call and returns (in response) the OIDs and
221// metadata of all the children of OID. The metadata set should be loaded
222// with whatever metadata fields are to be requested.
223
224bool get_children (const text_t &OID, const text_t &collection,
225 const text_tset &metadata, bool getParents,
226 recptproto *collectproto, FilterResponse_t &response,
227 ostream &logout) {
228
229 response.clear();
230
231 comerror_t err;
232 FilterRequest_t request;
233 OptionValue_t option;
234
235 option.name = "ParentNode";
236 option.value = OID;
237 request.filterOptions.push_back (option);
238 request.filterName = "BrowseFilter";
239 request.filterResultOptions = FROID | FRmetadata;
240 request.fields = metadata;
241 request.getParents = getParents;
242
243 collectproto->filter (collection, request, response, err, logout);
244
245 if (err != noError) {
246 outconvertclass text_t2ascii;
247 logout << text_t2ascii
248 << "Error: call to filter failed for " << OID
249 << " in OIDtools::get_children ("
250 << get_comerror_string (err) << ")\n";
251 return false;
252 }
253 return true;
254}
255
256// get_parent returns the parent of the document or classification
257// specified by OID
258text_t get_parent (text_t OID) {
259
260 if (OID.empty() || is_top (OID)) return "";
261
262 text_t::const_iterator begin = OID.begin();
263 text_t::const_iterator here = (OID.end() - 1);
264
265 while (here >= begin) {
266 OID.pop_back();
267 if (*here == '.') break;
268 here --;
269 }
270 return OID;
271}
272
273// takes an OID like ".2 and replaces the " with parent
274void translate_parent (text_t &OID, const text_t &parent) {
275
276 text_t::const_iterator here = OID.begin();
277 text_t::const_iterator end = OID.end();
278 text_t temp;
279
280 while (here != end) {
281 if (*here == '"') temp += parent;
282 else temp.push_back (*here);
283 here ++;
284 }
285 OID = temp;
286}
287
288// shrink_parent does the opposite to translate_parent
289void shrink_parent (text_t &OID) {
290
291 text_tarray tmp;
292 splitchar (OID.begin(), OID.end(), '.', tmp);
293 OID = "\"." + tmp.back();
294}
295
296// checks if OID uses ".fc", ".lc", ".pr", ".ns",
297// or ".ps" syntax (first child, last child, parent,
298// next sibling, previous sibling)
299bool needs_translating (const text_t &OID) {
300
301 if (OID.size() < 4) return false;
302
303 text_t tail = substr (OID.end()-3, OID.end());
304 if (tail == ".fc" || tail == ".lc" || tail == ".pr" ||
305 tail == ".ns" || tail == ".ps") return true;
306
307 return false;
308}
309
310// strips the ".fc", ".lc", ".pr", ".ns",
311// or ".ps" suffix from the end of OID
312void strip_suffix (text_t &OID) {
313
314 text_t tail = substr (OID.end()-3, OID.end());
315 while (tail == ".fc" || tail == ".lc" || tail == ".pr" ||
316 tail == ".ns" || tail == ".ps") {
317 OID.erase (OID.end()-3, OID.end());
318 tail = substr (OID.end()-3, OID.end());
319 }
320}
321
322static void recurse_contents (ResultDocInfo_t section, const bool &is_classify,
323 const text_t &collection, const text_tset &metadata,
324 recptproto *collectproto, FilterResponse_t &response,
325 ostream &logout) {
326
327 int haschildren = section.metadata["haschildren"].values[0].getint();
328 const text_t &doctype = section.metadata["doctype"].values[0];
329
330 if ((haschildren == 1) && ((!is_classify) || (doctype == "classify"))) {
331 FilterResponse_t tmp;
332 bool getParents = false;
333 get_children (section.OID, collection, metadata, getParents, collectproto, tmp, logout);
334 ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin();
335 ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end();
336 while (thisdoc != lastdoc) {
337 response.docInfo.push_back (*thisdoc);
338 recurse_contents (*thisdoc, is_classify, collection, metadata,
339 collectproto, response, logout);
340 thisdoc ++;
341 }
342 }
343}
344
345// get_contents returns OIDs and metadata of all contents
346// below (and including) OID.
347void get_contents (const text_t &topOID, const bool &is_classify,
348 text_tset &metadata, const text_t &collection,
349 recptproto *collectproto, FilterResponse_t &response,
350 ostream &logout) {
351
352 if (topOID.empty()) return;
353 response.clear();
354
355 metadata.insert ("haschildren");
356 metadata.insert ("doctype");
357
358 // get topOIDs info
359 if (get_info (topOID, collection, metadata, false, collectproto, response, logout))
360 recurse_contents (response.docInfo[0], is_classify, collection,
361 metadata, collectproto, response, logout);
362}
363
364// is_child_of returns true if OID2 is a child of OID1
365bool is_child_of(const text_t &OID1, const text_t &OID2) {
366
367 text_t parent = get_parent(OID2);
368
369 while (!parent.empty()) {
370 if (parent == OID1) return true;
371 parent = get_parent(parent);
372 }
373 return false;
374}
Note: See TracBrowser for help on using the repository browser.