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

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

changed around the way browsetools works

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