source: gsdl/trunk/runtime-src/src/oaiservr/listsetsaction.cpp@ 20574

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

Removed unused output_content() function in listsetsaction.

  • Property svn:keywords set to Author Date Id Revision
File size: 8.4 KB
Line 
1#include "listsetsaction.h"
2
3#if defined(GSDL_USE_STL_H)
4#include <fstream.h>
5#else
6#include <fstream>
7#endif
8
9#include "recptprototools.h"
10#include "oaitools.h"
11
12bool listsetsaction::validateAction(recptproto *protocol, oaiargs &params)
13{
14 // ----------------------------------------------------------------------------
15 // 1. Check for invalid arguments
16 // ----------------------------------------------------------------------------
17 bool invalid_argument_supplied = false;
18 text_tmap::const_iterator param_iterator = params.begin();
19 while (param_iterator != params.end())
20 {
21 // Check for arguments that aren't valid for this action
22 if (param_iterator->first != "verb" &&
23 param_iterator->first != "resumptionToken")
24 {
25 // We've found an invalid argument
26 invalid_argument_supplied = true;
27
28 // Delete the invalid argument from the list so it doesn't end up in the <request> tag that is returned
29 params.erase(param_iterator->first);
30 }
31
32 param_iterator++;
33 }
34
35 // If we found an invalid argument it's an error, so don't go any further
36 if (invalid_argument_supplied)
37 {
38 this->errorType = "badArgument";
39 return false;
40 }
41
42 // ----------------------------------------------------------------------------
43 // 2. Handle any exclusive arguments
44 // ----------------------------------------------------------------------------
45
46 // The resumptionToken argument is exclusive
47 if (params["resumptionToken"] != "")
48 {
49 // This argument is exclusive, so no other arguments are allowed (except "verb" of course)
50 if (params.getSize() != 2)
51 {
52 this->errorType = "badArgument";
53 return false;
54 }
55
56 // Check the resumption token is valid
57 ResumptionToken token(params["resumptionToken"]);
58 if (true) // TO DO: Fix this (the token.isValid() function is useless for ListSets)
59 {
60 // Everything is fine, and we don't continue further because this is an exclusive argument
61 this->errorType = "";
62 return true;
63 }
64 else
65 {
66 // There was an error with the resumption token
67 this->errorType = "badResumptionToken";
68 return false;
69 }
70 }
71
72 // ----------------------------------------------------------------------------
73 // 3. Handle any required arguments
74 // ----------------------------------------------------------------------------
75
76 // None!
77
78 // ----------------------------------------------------------------------------
79 // 4. Check any remaining arguments
80 // ----------------------------------------------------------------------------
81
82 // None!
83
84 // If we've reached here everything must be fine
85 this->errorType = "";
86 return true;
87}
88
89
90bool listsetsaction::output_content(ostream &output, recptproto *protocol, oaiargs &params)
91{
92 // output the total list of classifier points
93
94 // variables required
95 text_t browseOID = "browse";
96 FilterResponse_t response;
97 comerror_t err;
98 text_tarray & collections = this->configuration->getCollectionsList();
99 text_tset metadata;
100 ofstream logout("oai.log", ios::app);
101
102 // get a list of the collections available
103 // protocol->get_collection_list(collections, err, output);
104 if (collections.size() == 0) {
105 logout << "Found *no* OAI collections - check main.cfg for oaicollection items and read the OAI documentation.\n";
106 }
107
108 // check resumption token
109 int startSet = 0;
110 if (params["resumptionToken"] != "") {
111 ResumptionToken token(params["resumptionToken"]);
112 startSet = token.getPosition() - 1; // first document is said to be 1..
113 }
114 this->replyToken = NULL;
115
116 this->setNumber = 0;
117 this->setsOutput = 0;
118 for(int current_col = 0; current_col < collections.size(); ++current_col) {
119 // output the collection as a set, first, then its children
120 text_t gsdlCollect = collections[current_col];
121
122 if (this->setsOutput == this->configuration->resumeAfter())
123 {
124 this->replyToken = new ResumptionToken("", "", "");
125 this->replyToken->setPosition("", this->setNumber+1);
126 break;
127 }
128
129 if (this->setNumber >= startSet)
130 {
131 output << " <set>" << endl;
132 output << " <setSpec>" << gsdlCollect << "</setSpec>" << endl;;
133 output << " <setName>" << gsdlCollect << "</setName>" << endl;
134 output << " </set>" << endl;
135 this->setsOutput++;
136 }
137 setNumber++;
138
139 // get all the children of the (relevant) classifier data structures
140 get_children(browseOID, gsdlCollect, "", metadata, false, protocol, response, logout);
141 // and send them to the "recurse_content" list
142 for (int c = 0; c < response.numDocs; ++c) {
143 this->recurse_content(output, protocol, gsdlCollect, response.docInfo[c].OID, gsdlCollect, startSet);
144 }
145 }
146
147 // do a resumption token if required; errors cancel a token...
148 if (this->replyToken != NULL && this->errorType == "") {
149 // Don't add any whitespace around the resumption token as it can confuse harvesters/validators
150 output << " <resumptionToken>" << this->replyToken->getToken() << "</resumptionToken>" << endl;
151 }
152
153 return true;
154}
155
156void listsetsaction::recurse_content(ostream &output, recptproto *protocol, text_t &collection,
157 const text_t &classifier, text_t setHierarchy, int startSet)
158{
159 // metadata for this call
160 FilterResponse_t response;
161 text_tset metadata;
162 ofstream logout("oai.log", ios::app);
163
164 if (this->setsOutput == this->configuration->resumeAfter())
165 {
166 this->replyToken = new ResumptionToken("", "", "");
167 this->replyToken->setPosition("", this->setNumber+1);
168 return;
169 }
170
171 metadata.insert("contains");
172 metadata.insert("Title");
173 metadata.insert("supportsmemberof");
174
175 // get the document information
176 if (!get_info(classifier, collection, "", metadata, false, protocol, response, logout)) {
177 //cerr << "recurse content: Bad identifier or protocol " << classifier << endl;
178 return;
179 }
180
181 // check for top-level classifiers, check if the set name includes a '.'; if
182 // not, it is a top-level classifier: check for memberof support. Those without
183 // memberof support will not be supported on OAI
184 if (findchar(classifier.begin(), classifier.end(), '.') == classifier.end()) {
185 if (response.docInfo[0].metadata["supportsmemberof"].values.size() > 0) {
186 text_t memberOf = response.docInfo[0].metadata["supportsmemberof"].values[0];
187 if (memberOf != "true") {
188 return;
189 }
190 }
191 else {
192 return;
193 }
194 }
195
196 MetadataInfo_tmap::iterator here = response.docInfo[0].metadata.begin();
197 MetadataInfo_tmap::iterator end = response.docInfo[0].metadata.end();
198 text_t title;
199
200 while (here != end)
201 {
202 // Each set should only have one title - hence we only output one title here
203 // (it is a set title, not a collection)
204 if (here->first == "Title" && here->second.values.size() > 0) {
205 title = here->second.values[0];
206 }
207
208 ++here;
209 }
210
211 // output the xml for this set; use the classifier id for the name
212 // if the title is blank
213 // curSet holds the colon-separated sequence of parent sets of the current set
214 text_t curSet;
215 if (this->setNumber >= startSet)
216 {
217 output << " <set>" << endl;
218 text_t oai_classifier = classifier;
219 oaiclassifier::toOAI(collection, oai_classifier);
220 output << " <setSpec>" << oai_classifier << "</setSpec>" << endl;
221 output << " <setName>";
222 if (!title.empty()) {
223 curSet = setHierarchy + ":" + title;
224 }
225 else {
226 curSet = classifier; // Pretty much never gets here (shouldn't, at least)
227 }
228 output << curSet;
229 output << "</setName>" << endl;
230 output << " </set>" << endl;
231 this->setsOutput++;
232 }
233 this->setNumber++;
234
235 // get the children of this classifier and iterate them
236 get_children(classifier, collection, "", metadata, false, protocol, response, logout);
237 for (int c = 0; c < response.numDocs; ++c) {
238 text_t child = response.docInfo[c].OID;
239
240 if (child == classifier)
241 continue;
242
243 // check for non classifier items and exclude them
244 text_t childHead;
245 text_t::const_iterator start = child.begin();
246 text_t::const_iterator here = child.begin();
247 here += 2;
248 childHead = substr(start, here);
249
250 if (childHead != "CL")
251 continue;
252
253 // Recurse for "proper" classifier children. Pass curSet, the colon-separated list of
254 // parent sets. curSet is pass-by-value, so that as we step out of recursion we remember
255 // old set hierarchies.
256 this->recurse_content(output, protocol, collection, child, curSet, startSet);
257 }
258
259 return;
260}
Note: See TracBrowser for help on using the repository browser.