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

Last change on this file since 22286 was 20708, checked in by mdewsnip, 15 years ago

Same fix as made to identifyaction.cpp, to use a utf8outconvertclass when writing output so Unicode characters are correctly encoded as UTF-8.

  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 KB
Line 
1#include "listsetsaction.h"
2
3#include "resumptiontoken.h"
4#include "recptprototools.h"
5#include "oaitools.h"
6
7
8bool listsetsaction::validateAction(recptproto *protocol, oaiargs &params)
9{
10 // ----------------------------------------------------------------------------
11 // 1. Check for invalid arguments
12 // ----------------------------------------------------------------------------
13 bool invalid_argument_supplied = false;
14 text_tmap::const_iterator param_iterator = params.begin();
15 while (param_iterator != params.end())
16 {
17 // Check for arguments that aren't valid for this action
18 if (param_iterator->first != "verb" &&
19 param_iterator->first != "resumptionToken")
20 {
21 // We've found an invalid argument
22 invalid_argument_supplied = true;
23
24 // Delete the invalid argument from the list so it doesn't end up in the <request> tag that is returned
25 params.erase(param_iterator->first);
26 }
27
28 param_iterator++;
29 }
30
31 // If we found an invalid argument it's an error, so don't go any further
32 if (invalid_argument_supplied)
33 {
34 this->errorType = "badArgument";
35 return false;
36 }
37
38 // ----------------------------------------------------------------------------
39 // 2. Handle any exclusive arguments
40 // ----------------------------------------------------------------------------
41
42 // The resumptionToken argument is exclusive
43 if (params["resumptionToken"] != "")
44 {
45 // This argument is exclusive, so no other arguments are allowed (except "verb" of course)
46 if (params.getSize() != 2)
47 {
48 this->errorType = "badArgument";
49 return false;
50 }
51
52 // Check the resumption token is valid
53 ResumptionToken token(params["resumptionToken"]);
54 if (token.isValid())
55 {
56 // Everything is fine, and we don't continue further because this is an exclusive argument
57 this->errorType = "";
58 return true;
59 }
60 else
61 {
62 // There was an error with the resumption token
63 this->errorType = "badResumptionToken";
64 return false;
65 }
66 }
67
68 // ----------------------------------------------------------------------------
69 // 3. Handle any required arguments
70 // ----------------------------------------------------------------------------
71
72 // None!
73
74 // ----------------------------------------------------------------------------
75 // 4. Check any remaining arguments
76 // ----------------------------------------------------------------------------
77
78 // None!
79
80 // If we've reached here everything must be fine
81 this->errorType = "";
82 return true;
83}
84
85
86bool listsetsaction::output_content(ostream &output, recptproto *protocol, oaiargs &params)
87{
88 // Reset variables
89 this->setsOutput = 0;
90
91 text_t position = "";
92
93 // Process the resumptionToken if there is one
94 if (params["resumptionToken"] != "")
95 {
96 ResumptionToken resumption_token(params["resumptionToken"]);
97 position = resumption_token.getPosition();
98 }
99
100 // Get a list of the collections available
101 text_tarray& collections = this->configuration->getCollectionsList();
102 if (collections.size() == 0)
103 {
104 return false;
105 }
106
107 // Get the current collection from the position value
108 text_t collection_name = "";
109 oaiclassifier::toGSDL(collection_name, position);
110
111 // Find the starting collection
112 text_tarray::iterator collection_iterator = collections.begin();
113 while (collection_iterator != collections.end())
114 {
115 if (collection_name == "" || collection_name == *collection_iterator)
116 {
117 break;
118 }
119
120 collection_iterator++;
121 }
122
123 // Now loop through the remaining collections
124 while (collection_iterator != collections.end())
125 {
126 collection_name = (*collection_iterator);
127
128 // If we've output the desired number of records return a resumptionToken and we're done
129 if (this->setsOutput == this->configuration->resumeAfter())
130 {
131 ResumptionToken resumption_token("", "", "", "", "", collection_name);
132
133 // Don't add any whitespace around the resumption token as it can confuse harvesters/validators
134 output << " <resumptionToken>" << resumption_token.getResumptionTokenString() << "</resumptionToken>" << endl;
135 return true;
136 }
137
138 // If output_content_for_col() returns false a resumption token has been output, so it's time to stop
139 if (output_content_for_col(output, protocol, params, collection_name) == false)
140 {
141 return true;
142 }
143
144 collection_iterator++;
145 }
146
147 return true;
148}
149
150
151bool listsetsaction::output_content_for_col(ostream &output, recptproto *protocol, oaiargs &params, text_t collection)
152{
153 utf8outconvertclass utf8convert;
154 text_t position = "";
155
156 // Process the resumptionToken if there is one
157 if (params["resumptionToken"] != "")
158 {
159 ResumptionToken resumption_token(params["resumptionToken"]);
160 position = resumption_token.getPosition();
161 }
162
163 // Get the list of sets in this collection
164 // Collections should not contain too many sets otherwise this will use a lot of time and memory
165 text_tset metadata; // Must be empty for efficiency
166 FilterResponse_t sets_response;
167 get_children("browse", collection, "", metadata, false, protocol, sets_response, *this->logout);
168
169 // Find the starting position, if necessary
170 ResultDocInfo_tarray::iterator set_iterator = sets_response.docInfo.begin();
171 if (this->setsOutput == 0)
172 {
173 while (set_iterator != sets_response.docInfo.end())
174 {
175 if (position == "" || position == (collection + ":" + (*set_iterator).OID))
176 {
177 break;
178 }
179
180 set_iterator++;
181 }
182 }
183
184 // Output the collection as a set
185 if (position == "" || position == collection)
186 {
187 output << utf8convert << " <set>\n";
188 output << utf8convert << " <setSpec>" << collection << "</setSpec>\n";
189 if (this->configuration->getSetName(collection) != "")
190 {
191 output << utf8convert << " <setName>" << this->configuration->getSetName(collection) << "</setName>\n";
192 }
193 else
194 {
195 output << utf8convert << " <setName>" << collection << "</setName>\n";
196 }
197 if (this->configuration->getSetDescription(collection) != "")
198 {
199 output << utf8convert << " <setDescription>" << this->configuration->getSetDescription(collection) << "</setDescription>\n";
200 }
201 output << utf8convert << " </set>\n";
202 this->setsOutput++;
203 }
204
205 // Now loop through displaying the next matching records
206 while (set_iterator != sets_response.docInfo.end())
207 {
208 text_t set = (*set_iterator).OID;
209
210 // Only classifiers with supportsmemberof become OAI sets, for reasons I don't really understand
211 text_tset set_metadata;
212 set_metadata.insert("supportsmemberof");
213 set_metadata.insert("Title");
214 FilterResponse_t set_response;
215 get_info(set, collection, "", set_metadata, false, protocol, set_response, *this->logout);
216
217 if (set_response.docInfo[0].metadata["supportsmemberof"].values.size() > 0 && set_response.docInfo[0].metadata["supportsmemberof"].values[0] == "true")
218 {
219 // If we've output the desired number of records return a resumptionToken and we're done
220 if (this->setsOutput == this->configuration->resumeAfter())
221 {
222 ResumptionToken resumption_token("", "", "", "", "", collection + ":" + set);
223
224 // Don't add any whitespace around the resumption token as it can confuse harvesters/validators
225 output << " <resumptionToken>" << resumption_token.getResumptionTokenString() << "</resumptionToken>" << endl;
226 return false;
227 }
228
229 // Otherwise output this set and increment the count
230 output << utf8convert << " <set>\n";
231 output << utf8convert << " <setSpec>" << collection << ":" << set << "</setSpec>\n";
232 if (this->configuration->getSetName(collection + ":" + set) != "")
233 {
234 output << utf8convert << " <setName>" << this->configuration->getSetName(collection + ":" + set) << "</setName>\n";
235 }
236 else
237 {
238 output << utf8convert << " <setName>" << set_response.docInfo[0].metadata["Title"].values[0] << "</setName>\n";
239 }
240 if (this->configuration->getSetDescription(collection + ":" + set) != "")
241 {
242 output << utf8convert << " <setDescription>" << this->configuration->getSetDescription(collection + ":" + set) << "</setDescription>\n";
243 }
244 output << utf8convert << " </set>\n";
245 this->setsOutput++;
246 }
247
248 set_iterator++;
249 }
250
251 return true;
252}
Note: See TracBrowser for help on using the repository browser.