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

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

small change to allow FullTOC option

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