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

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

small change to allow FullTOC option

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