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

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

changed FilterRequest_t::docSet into an array

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