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

Last change on this file since 1285 was 1285, checked in by sjboddie, 24 years ago

Removed CVS logging information from source files

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1/**********************************************************************
2 *
3 * OIDtools.cpp --
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
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.
9 *
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 *
24 *********************************************************************/
25
26#include "OIDtools.h"
27
28
29// returns (in top) the top level of OID (i.e. everything
30// up until the first dot)
31void get_top (const text_t &OID, text_t &top) {
32
33 top.clear();
34 if (OID.empty()) return;
35
36 text_t::const_iterator begin = OID.begin();
37 text_t::const_iterator end = OID.end();
38
39 top.appendrange (begin, findchar(begin, end, '.'));
40}
41
42
43// checks if OID is top level (i.e. contains no dots)
44bool is_top (const text_t &OID) {
45
46 if (OID.empty()) return true;
47
48 text_t::const_iterator here = OID.begin();
49 text_t::const_iterator end = OID.end();
50 here = findchar (here, end, '.');
51
52 if (here == end) return true;
53 return false;
54}
55
56
57// get_parents_array loads the parents array with all the parents of the
58// document or classification specified by OID (not including OID itself)
59void get_parents_array (const text_t &OID, text_tarray &parents) {
60
61 text_t::const_iterator here = OID.begin ();
62 text_t::const_iterator end = OID.end ();
63 text_t thisparent;
64
65 while (here != end) {
66 if (*here == '.') parents.push_back(thisparent);
67 thisparent.push_back(*here);
68 here ++;
69 }
70}
71
72
73// get_info does a protocol call and returns (in response) the metadata
74// associated with OID. Metadata should be loaded with whatever
75// metadata fields are to be requested.
76
77bool get_info (const text_t &OID, const text_t &collection,
78 const text_tset &metadata, bool getParents,
79 recptproto *collectproto, FilterResponse_t &response,
80 ostream &logout) {
81
82 response.clear();
83
84 comerror_t err;
85 FilterRequest_t request;
86
87 request.filterName = "NullFilter";
88 request.filterResultOptions = FRmetadata;
89 request.getParents = getParents;
90 request.fields = metadata;
91 request.docSet.push_back (OID);
92
93 collectproto->filter (collection, request, response, err, logout);
94 if (err != noError) {
95 outconvertclass text_t2ascii;
96 logout << text_t2ascii
97 << "Error: call to filter failed for " << OID
98 << " in OIDtools::get_info ("
99 << get_comerror_string (err) << ")\n";
100 return false;
101 }
102
103 return true;
104}
105
106bool get_info (const text_tarray &OIDs, const text_t &collection,
107 const text_tset &metadata, bool getParents,
108 recptproto *collectproto, FilterResponse_t &response,
109 ostream &logout) {
110
111 response.clear();
112 if (OIDs.empty()) return true;
113
114 comerror_t err;
115 FilterRequest_t request;
116
117 request.filterName = "NullFilter";
118 request.filterResultOptions = FRmetadata;
119 request.getParents = getParents;
120 request.fields = metadata;
121
122 request.docSet = OIDs;
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 in OIDtools::get_info ("
129 << get_comerror_string (err) << ")\n";
130 return false;
131 }
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_tset metadata;
142 metadata.insert ("haschildren");
143
144 if (get_info (OID, collection, metadata, false, collectproto, response, logout)) {
145 if (response.docInfo[0].metadata["haschildren"].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 set 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_tset &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
254static void recurse_contents (ResultDocInfo_t section, const bool &is_classify,
255 const text_t &collection, const text_tset &metadata,
256 recptproto *collectproto, FilterResponse_t &response,
257 ostream &logout) {
258
259 int haschildren = section.metadata["haschildren"].values[0].getint();
260 const text_t &doctype = section.metadata["doctype"].values[0];
261
262 if ((haschildren == 1) && ((!is_classify) || (doctype == "classify"))) {
263 FilterResponse_t tmp;
264 bool getParents = false;
265 get_children (section.OID, collection, metadata, getParents, collectproto, tmp, logout);
266 ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin();
267 ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end();
268 while (thisdoc != lastdoc) {
269 response.docInfo.push_back (*thisdoc);
270 recurse_contents (*thisdoc, is_classify, collection, metadata,
271 collectproto, response, logout);
272 thisdoc ++;
273 }
274 }
275}
276
277// get_contents returns OIDs and metadata of all contents
278// below (and including) OID.
279void get_contents (const text_t &topOID, const bool &is_classify,
280 text_tset &metadata, const text_t &collection,
281 recptproto *collectproto, FilterResponse_t &response,
282 ostream &logout) {
283
284 if (topOID.empty()) return;
285 response.clear();
286
287 metadata.insert ("haschildren");
288 metadata.insert ("doctype");
289
290 // get topOIDs info
291 if (get_info (topOID, collection, metadata, false, collectproto, response, logout))
292 recurse_contents (response.docInfo[0], is_classify, collection,
293 metadata, collectproto, response, logout);
294}
295
296// is_child_of returns true if OID2 is a child of OID1
297bool is_child_of(const text_t &OID1, const text_t &OID2) {
298
299 text_t parent = get_parent(OID2);
300
301 while (!parent.empty()) {
302 if (parent == OID1) return true;
303 parent = get_parent(parent);
304 }
305 return false;
306}
Note: See TracBrowser for help on using the repository browser.