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

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

added extra check in get_info

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