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

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

get_children now takes a getParents argument

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