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

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

added overloaded get_info function for getting info on multiple OIDs

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