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

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

get_info() now takes a getParents argument

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