source: main/trunk/greenstone2/runtime-src/src/oaiservr/listsetsaction.cpp@ 27553

Last change on this file since 27553 was 27553, checked in by ak19, 11 years ago

Function needed to return a bool in order to compile.

  • Property svn:keywords set to Author Date Id Revision
File size: 10.8 KB
Line 
1/**********************************************************************
2 *
3 * listsetsaction.cpp --
4 *
5 * Copyright (C) 2004-2010 The New Zealand Digital Library Project
6 *
7 * A component of the Greenstone digital library software
8 * from the New Zealand Digital Library Project at the
9 * University of Waikato, New Zealand.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 *********************************************************************/
26
27#include "listsetsaction.h"
28
29#include "resumptiontoken.h"
30#include "recptprototools.h"
31#include "oaitools.h"
32
33
34bool listsetsaction::validateAction(recptproto *protocol, oaiargs &params)
35{
36 // ----------------------------------------------------------------------------
37 // 1. Check for invalid arguments
38 // ----------------------------------------------------------------------------
39 bool invalid_argument_supplied = false;
40 text_tmap::const_iterator param_iterator = params.begin();
41 while (param_iterator != params.end())
42 {
43 // Check for arguments that aren't valid for this action
44 if (param_iterator->first != "verb" &&
45 param_iterator->first != "resumptionToken")
46 {
47 // We've found an invalid argument
48 invalid_argument_supplied = true;
49
50 // Delete the invalid argument from the list so it doesn't end up in the <request> tag that is returned
51 params.erase(param_iterator->first);
52 }
53
54 param_iterator++;
55 }
56
57 // If we found an invalid argument it's an error, so don't go any further
58 if (invalid_argument_supplied)
59 {
60 this->errorType = "badArgument";
61 return false;
62 }
63
64 // ----------------------------------------------------------------------------
65 // 2. Handle any exclusive arguments
66 // ----------------------------------------------------------------------------
67
68 // The resumptionToken argument is exclusive
69 if (params["resumptionToken"] != "")
70 {
71 // This argument is exclusive, so no other arguments are allowed (except "verb" of course)
72 if (params.getSize() != 2)
73 {
74 this->errorType = "badArgument";
75 return false;
76 }
77
78 // Check the resumption token is valid
79 ResumptionToken token(params["resumptionToken"]);
80 if (token.isValid())
81 {
82 // Everything is fine, and we don't continue further because this is an exclusive argument
83 this->errorType = "";
84 return true;
85 }
86 else
87 {
88 // There was an error with the resumption token
89 this->errorType = "badResumptionToken";
90 return false;
91 }
92 }
93
94 // ----------------------------------------------------------------------------
95 // 3. Handle any required arguments
96 // ----------------------------------------------------------------------------
97
98 // None!
99
100 // ----------------------------------------------------------------------------
101 // 4. Check any remaining arguments
102 // ----------------------------------------------------------------------------
103
104 // None!
105
106 // If we've reached here everything must be fine
107 this->errorType = "";
108 return true;
109}
110
111
112bool listsetsaction::output_content(ostream &output, recptproto *protocol, oaiargs &params)
113{
114 // Reset variables
115 this->setsOutput = 0;
116
117 text_t position = "";
118
119 // Process the resumptionToken if there is one
120 if (params["resumptionToken"] != "")
121 {
122 ResumptionToken resumption_token(params["resumptionToken"]);
123 position = resumption_token.getPosition();
124 }
125
126 // if no resumption token, output the super colls. Otherwise, start from
127 // the collection list correct position.
128 // Assume for now that super coll list is always first in the list of sets,
129 // and we never issue a resumption token part way through the list of super colls
130 // TODO handle resumption tokens properly.
131 text_t set_name ="";
132 if (position == "") {
133 text_tarray& supercolls = this->configuration->getSuperCollectionsList();
134 text_tarray::iterator supercoll_iterator = supercolls.begin();
135 while (supercoll_iterator != supercolls.end()) {
136 set_name = (*supercoll_iterator);
137 output_content_for_supercol(output, set_name);
138 supercoll_iterator++;
139 }
140 }
141
142
143 // Get a list of the collections available
144 text_tarray& collections = this->configuration->getCollectionsList();
145 if (collections.size() == 0)
146 {
147 if (this->setsOutput ==0) {
148 // we had no super colls either
149 return false;
150 }
151 return true;
152 }
153
154 // Get the current collection from the position value
155 text_t collection_name = "";
156 oaiclassifier::toGSDL(collection_name, position);
157
158 // Find the starting collection
159 text_tarray::iterator collection_iterator = collections.begin();
160 while (collection_iterator != collections.end())
161 {
162 if (collection_name == "" || collection_name == *collection_iterator)
163 {
164 break;
165 }
166
167 collection_iterator++;
168 }
169
170 // Now loop through the remaining collections
171 while (collection_iterator != collections.end())
172 {
173 collection_name = (*collection_iterator);
174
175 // If we've output the desired number of records return a resumptionToken and we're done
176 if (this->setsOutput == this->configuration->resumeAfter())
177 {
178 ResumptionToken resumption_token("", "", "", "", "", collection_name);
179
180 // Don't add any whitespace around the resumption token as it can confuse harvesters/validators
181 output << " <resumptionToken>" << resumption_token.getResumptionTokenString() << "</resumptionToken>" << endl;
182 return true;
183 }
184
185 // If output_content_for_col() returns false a resumption token has been output, so it's time to stop
186 if (output_content_for_col(output, protocol, params, collection_name) == false)
187 {
188 return true;
189 }
190
191 collection_iterator++;
192 }
193
194 return true;
195}
196
197bool listsetsaction::output_content_for_supercol(ostream &output, text_t supercoll) {
198 utf8outconvertclass utf8convert;
199 output << utf8convert << " <set>\n";
200 output << utf8convert << " <setSpec>" << supercoll << "</setSpec>\n";
201 if (this->configuration->getSetName(supercoll) != "")
202 {
203 output << utf8convert << " <setName>" << this->configuration->getSetName(supercoll) << "</setName>\n";
204 }
205 else
206 {
207 output << utf8convert << " <setName>" << supercoll << "</setName>\n";
208 }
209 if (this->configuration->getSetDescription(supercoll) != "")
210 {
211 output << utf8convert << " <setDescription>" << this->configuration->getSetDescription(supercoll) << "</setDescription>\n";
212 }
213 output << utf8convert << " </set>\n";
214 this->setsOutput++;
215 return true;
216}
217
218
219
220
221bool listsetsaction::output_content_for_col(ostream &output, recptproto *protocol, oaiargs &params, text_t collection)
222{
223 utf8outconvertclass utf8convert;
224 text_t position = "";
225
226 // Process the resumptionToken if there is one
227 if (params["resumptionToken"] != "")
228 {
229 ResumptionToken resumption_token(params["resumptionToken"]);
230 position = resumption_token.getPosition();
231 }
232
233 // Get the list of sets in this collection
234 // Collections should not contain too many sets otherwise this will use a lot of time and memory
235 text_tset metadata; // Must be empty for efficiency
236 FilterResponse_t sets_response;
237 get_children("browse", collection, "", metadata, false, protocol, sets_response, *this->logout);
238
239 // Find the starting position, if necessary
240 ResultDocInfo_tarray::iterator set_iterator = sets_response.docInfo.begin();
241 if (this->setsOutput == 0)
242 {
243 while (set_iterator != sets_response.docInfo.end())
244 {
245 if (position == "" || position == (collection + ":" + (*set_iterator).OID))
246 {
247 break;
248 }
249
250 set_iterator++;
251 }
252 }
253
254 // Output the collection as a set
255 if (position == "" || position == collection)
256 {
257 output << utf8convert << " <set>\n";
258 output << utf8convert << " <setSpec>" << collection << "</setSpec>\n";
259 if (this->configuration->getSetName(collection) != "")
260 {
261 output << utf8convert << " <setName>" << this->configuration->getSetName(collection) << "</setName>\n";
262 }
263 else
264 {
265 output << utf8convert << " <setName>" << collection << "</setName>\n";
266 }
267 if (this->configuration->getSetDescription(collection) != "")
268 {
269 output << utf8convert << " <setDescription>" << this->configuration->getSetDescription(collection) << "</setDescription>\n";
270 }
271 output << utf8convert << " </set>\n";
272 this->setsOutput++;
273 }
274
275 // Now loop through displaying the next matching records
276 while (set_iterator != sets_response.docInfo.end())
277 {
278 text_t set = (*set_iterator).OID;
279
280 // Only classifiers with supportsmemberof become OAI sets, for reasons I don't really understand
281 text_tset set_metadata;
282 set_metadata.insert("supportsmemberof");
283 set_metadata.insert("Title");
284 FilterResponse_t set_response;
285 get_info(set, collection, "", set_metadata, false, protocol, set_response, *this->logout);
286
287 if (set_response.docInfo[0].metadata["supportsmemberof"].values.size() > 0 && set_response.docInfo[0].metadata["supportsmemberof"].values[0] == "true")
288 {
289 // If we've output the desired number of records return a resumptionToken and we're done
290 if (this->setsOutput == this->configuration->resumeAfter())
291 {
292 ResumptionToken resumption_token("", "", "", "", "", collection + ":" + set);
293
294 // Don't add any whitespace around the resumption token as it can confuse harvesters/validators
295 output << " <resumptionToken>" << resumption_token.getResumptionTokenString() << "</resumptionToken>" << endl;
296 return false;
297 }
298
299 // Otherwise output this set and increment the count
300 output << utf8convert << " <set>\n";
301 output << utf8convert << " <setSpec>" << collection << ":" << set << "</setSpec>\n";
302 if (this->configuration->getSetName(collection + ":" + set) != "")
303 {
304 output << utf8convert << " <setName>" << this->configuration->getSetName(collection + ":" + set) << "</setName>\n";
305 }
306 else
307 {
308 output << utf8convert << " <setName>" << set_response.docInfo[0].metadata["Title"].values[0] << "</setName>\n";
309 }
310 if (this->configuration->getSetDescription(collection + ":" + set) != "")
311 {
312 output << utf8convert << " <setDescription>" << this->configuration->getSetDescription(collection + ":" + set) << "</setDescription>\n";
313 }
314 output << utf8convert << " </set>\n";
315 this->setsOutput++;
316 }
317
318 set_iterator++;
319 }
320
321 return true;
322}
Note: See TracBrowser for help on using the repository browser.