source: gsdl/trunk/src/protocol/recptprototools.cpp@ 15836

Last change on this file since 15836 was 15836, checked in by mdewsnip, 16 years ago

(Adding dynamic classifiers) Not sure if this is necessarily the best place to do this, but added the ability to request the documents from a "get_documents_with_metadata_value()" call to be sorted based on a certain metadata element. Thanks to John Thompson for the SQL statement help.

  • Property svn:executable set to *
File size: 9.7 KB
Line 
1/**********************************************************************
2 *
3 * recptprototools.cpp --
4 * Copyright (C) 1999-2008 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 "recptprototools.h"
27#include <assert.h>
28
29
30// get_info does a protocol call and returns (in response) the metadata
31// associated with OID. Metadata should be loaded with whatever
32// metadata fields are to be requested.
33
34bool get_info (const text_t &OID, const text_t &collection, const text_t &lang,
35 const text_tset &metadata, bool getParents,
36 recptproto *collectproto, FilterResponse_t &response,
37 ostream &logout)
38{
39 response.clear();
40
41 comerror_t err = noError;
42 FilterRequest_t request;
43 request.clear();
44
45 request.filterName = "NullFilter";
46 request.filterLang = lang;
47 request.filterResultOptions = FRmetadata;
48 request.getParents = getParents;
49 request.fields = metadata;
50 request.docSet.push_back (OID);
51 assert (collectproto != NULL);
52
53 collectproto->filter (collection, request, response, err, logout);
54 if (err != noError)
55 {
56 outconvertclass text_t2ascii;
57 logout << text_t2ascii
58 << "Error: call to filter failed for " << OID
59 << " in OIDtools::get_info ("
60 << get_comerror_string (err) << ")\n";
61 return false;
62 }
63
64 return true;
65}
66
67
68// overloaded, to allow "custom" filter options.
69bool get_info (const text_t &OID, const text_t &collection, const text_t &lang,
70 const text_tset &metadata, const OptionValue_tarray &options,
71 bool getParents,
72 recptproto *collectproto, FilterResponse_t &response,
73 ostream &logout)
74{
75 response.clear();
76
77 comerror_t err = noError;
78 FilterRequest_t request;
79
80 request.filterName = "NullFilter";
81 request.filterLang = lang;
82 request.filterResultOptions = FRmetadata;
83 request.getParents = getParents;
84 request.filterOptions = options;
85 request.fields = metadata;
86 request.docSet.push_back (OID);
87
88 assert (collectproto != NULL);
89 collectproto->filter (collection, request, response, err, logout);
90 if (err != noError)
91 {
92 outconvertclass text_t2ascii;
93 logout << text_t2ascii
94 << "Error: call to filter failed for " << OID
95 << " in OIDtools::get_info ("
96 << get_comerror_string (err) << ")\n";
97 return false;
98 }
99
100 return true;
101}
102
103
104bool get_info (const text_tarray &OIDs, const text_t &collection, const text_t &lang,
105 const text_tset &metadata, bool getParents,
106 recptproto *collectproto, FilterResponse_t &response,
107 ostream &logout)
108{
109 response.clear();
110 if (OIDs.empty()) return true;
111
112 comerror_t err = noError;
113 FilterRequest_t request;
114
115 request.filterName = "NullFilter";
116 request.filterLang = lang;
117 request.filterResultOptions = FRmetadata;
118 request.getParents = getParents;
119 request.fields = metadata;
120
121 request.docSet = OIDs;
122
123 collectproto->filter (collection, request, response, err, logout);
124 if (err != noError)
125 {
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
137// has_children returns true if OID has children
138bool has_children (const text_t &OID, const text_t &collection, const text_t &lang,
139 recptproto *collectproto, ostream &logout) {
140
141 FilterResponse_t response;
142 text_tset metadata;
143 metadata.insert ("haschildren");
144
145 if (get_info (OID, collection, lang, metadata, false, collectproto, response, logout))
146 {
147 if (response.docInfo[0].metadata["haschildren"].values[0] == "1")
148 {
149 return true;
150 }
151 }
152
153 return false;
154}
155
156
157// get_children does a protocol call and returns (in response) the OIDs and
158// metadata of all the children of OID. The metadata set should be loaded
159// with whatever metadata fields are to be requested.
160
161bool get_children (const text_t &OID, const text_t &collection, const text_t &lang,
162 const text_tset &metadata, bool getParents,
163 recptproto *collectproto, FilterResponse_t &response,
164 ostream &logout)
165{
166 response.clear();
167
168 comerror_t err = noError;
169 FilterRequest_t request;
170 OptionValue_t option;
171
172 option.name = "ParentNode";
173 option.value = OID;
174 request.filterOptions.push_back (option);
175 request.filterName = "BrowseFilter";
176 request.filterLang = lang;
177 request.filterResultOptions = FROID;
178
179 // Efficiency improvement: only get the filter to retrieve metadata if some has been requested
180 // Otherwise, the filter makes an unnecessary request to the database for each child node
181 // By Michael Dewsnip, DL Consulting Ltd
182 if (metadata.size() > 0)
183 {
184 request.filterResultOptions |= FRmetadata;
185 }
186
187 request.fields = metadata;
188 request.getParents = getParents;
189
190 collectproto->filter (collection, request, response, err, logout);
191
192 if (err != noError)
193 {
194 outconvertclass text_t2ascii;
195 logout << text_t2ascii
196 << "Error: call to filter failed for " << OID
197 << " in OIDtools::get_children ("
198 << get_comerror_string (err) << ")\n";
199 return false;
200 }
201
202 return true;
203}
204
205
206static void recurse_contents (ResultDocInfo_t section, const bool &is_classify,
207 const text_t &collection, const text_t &lang,
208 const text_tset &metadata,
209 recptproto *collectproto, FilterResponse_t &response,
210 ostream &logout)
211{
212 int haschildren = section.metadata["haschildren"].values[0].getint();
213 const text_t &doctype = section.metadata["doctype"].values[0];
214
215 if ((haschildren == 1) && ((!is_classify) || (doctype == "classify")))
216 {
217 FilterResponse_t tmp;
218 bool getParents = false;
219 get_children (section.OID, collection, lang, metadata, getParents, collectproto, tmp, logout);
220 ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin();
221 ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end();
222 while (thisdoc != lastdoc)
223 {
224 response.docInfo.push_back (*thisdoc);
225 recurse_contents (*thisdoc, is_classify, collection, lang, metadata, collectproto, response, logout);
226 ++thisdoc;
227 }
228 }
229}
230
231
232// get_contents returns OIDs and metadata of all contents
233// below (and including) OID.
234void get_contents (const text_t &topOID, const bool &is_classify,
235 text_tset &metadata, const text_t &collection, const text_t &lang,
236 recptproto *collectproto, FilterResponse_t &response,
237 ostream &logout)
238{
239 if (topOID.empty()) return;
240 response.clear();
241
242 metadata.insert ("haschildren");
243 metadata.insert ("doctype");
244
245 // get topOIDs info
246 if (get_info (topOID, collection, lang, metadata, false, collectproto, response, logout))
247 {
248 recurse_contents (response.docInfo[0], is_classify, collection, lang, metadata, collectproto, response, logout);
249 }
250}
251
252
253bool get_metadata_values (const text_t metadata_element_name, const text_t &collection,
254 recptproto *collectproto, FilterResponse_t &response, ostream &logout)
255{
256 response.clear();
257
258 comerror_t err = noError;
259 FilterRequest_t request;
260 request.clear();
261
262 request.filterName = "SQLBrowseFilter";
263 request.requestParams = "GetMetadataValues";
264
265 OptionValue_t request_option;
266 request_option.name = "MetadataElement";
267 request_option.value = metadata_element_name;
268 request.filterOptions.push_back (request_option);
269
270 assert (collectproto != NULL);
271 collectproto->filter (collection, request, response, err, logout);
272 if (err != noError)
273 {
274 outconvertclass text_t2ascii;
275 logout << text_t2ascii
276 << "Error: call to filter failed for " << metadata_element_name
277 << " in OIDtools::get_metadata_values ("
278 << get_comerror_string (err) << ")\n";
279 return false;
280 }
281
282 return true;
283}
284
285
286bool get_documents_with_metadata_value (const text_t metadata_element_name, const text_t metadata_value,
287 const text_t sort_by_metadata_element_name, const text_t &collection,
288 recptproto *collectproto, FilterResponse_t &response, ostream &logout)
289{
290 response.clear();
291
292 comerror_t err = noError;
293 FilterRequest_t request;
294 request.clear();
295
296 request.filterName = "SQLBrowseFilter";
297 request.requestParams = "GetDocumentsWithMetadataValue";
298
299 OptionValue_t request_option;
300 request_option.name = "MetadataElement";
301 request_option.value = metadata_element_name;
302 request.filterOptions.push_back (request_option);
303 request_option.name = "MetadataValue";
304 request_option.value = metadata_value;
305 request.filterOptions.push_back (request_option);
306 request_option.name = "SortByMetadataElement";
307 request_option.value = sort_by_metadata_element_name;
308 request.filterOptions.push_back (request_option);
309
310 assert (collectproto != NULL);
311 collectproto->filter (collection, request, response, err, logout);
312 if (err != noError)
313 {
314 outconvertclass text_t2ascii;
315 logout << text_t2ascii
316 << "Error: call to filter failed for " << metadata_element_name << " = " << metadata_value
317 << " in OIDtools::get_documents_with_metadata_value ("
318 << get_comerror_string (err) << ")\n";
319 return false;
320 }
321
322 return true;
323}
Note: See TracBrowser for help on using the repository browser.