source: main/trunk/greenstone2/runtime-src/src/oaiservr/listrecsaction.cpp@ 28762

Last change on this file since 28762 was 27534, checked in by kjdon, 11 years ago

more changes for super collection stuff. Now can handle having collections in a super colleciton that are not in the main collection list

  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 KB
Line 
1/**********************************************************************
2 *
3 * listrecsaction.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 "listrecsaction.h"
28
29#include "oaitools.h"
30#include "recordaction.h"
31
32bool listrecsaction::validateAction(recptproto *protocol, oaiargs &params)
33{
34 // ----------------------------------------------------------------------------
35 // 1. Check for invalid arguments
36 // ----------------------------------------------------------------------------
37 bool invalid_argument_supplied = false;
38 text_tmap::const_iterator param_iterator = params.begin();
39 while (param_iterator != params.end())
40 {
41 // Check for arguments that aren't valid for this action
42 if (param_iterator->first != "verb" &&
43 param_iterator->first != "from" &&
44 param_iterator->first != "until" &&
45 param_iterator->first != "set" &&
46 param_iterator->first != "resumptionToken" &&
47 param_iterator->first != "metadataPrefix")
48 {
49 // We've found an invalid argument
50 invalid_argument_supplied = true;
51
52 // Delete the invalid argument from the list so it doesn't end up in the <request> tag that is returned
53 params.erase(param_iterator->first);
54 }
55
56 param_iterator++;
57 }
58
59 // If we found an invalid argument it's an error, so don't go any further
60 if (invalid_argument_supplied)
61 {
62 this->errorType = "badArgument";
63 return false;
64 }
65
66 // ----------------------------------------------------------------------------
67 // 2. Handle any exclusive arguments
68 // ----------------------------------------------------------------------------
69
70 // The resumptionToken argument is exclusive
71 if (params["resumptionToken"] != "")
72 {
73 // This argument is exclusive, so no other arguments are allowed (except "verb" of course)
74 if (params.getSize() != 2)
75 {
76 this->errorType = "badArgument";
77 return false;
78 }
79
80 // Check the resumption token is valid
81 ResumptionToken token(params["resumptionToken"]);
82 if (token.isValid())
83 {
84 // Everything is fine, and we don't continue further because this is an exclusive argument
85 this->errorType = "";
86 return true;
87 }
88 else
89 {
90 // There was an error with the resumption token
91 this->errorType = "badResumptionToken";
92 return false;
93 }
94 }
95
96 // ----------------------------------------------------------------------------
97 // 3. Handle any required arguments
98 // ----------------------------------------------------------------------------
99
100 // The metadataPrefix is required
101 text_t metadataPrefix = params["metadataPrefix"];
102
103 // Check that the metadataPrefix argument exists
104 if (metadataPrefix == "")
105 {
106 this->errorType = "badArgument";
107 return false;
108 }
109
110 // Check that the metadataPrefix is a format we support
111 if (this->formatNotSupported(metadataPrefix))
112 {
113 this->errorType = "cannotDisseminateFormat";
114 return false;
115 }
116
117 // ----------------------------------------------------------------------------
118 // 4. Check any remaining arguments
119 // ----------------------------------------------------------------------------
120
121 // Check "from" and "until" arguments
122 if (params["from"] != "" || params["until"] != "")
123 {
124 text_t from = params["from"];
125 text_t until = params["until"];
126
127 // Check the from date is in the correct format: YYYY-MM-DD
128 if (from != "")
129 {
130 // Must be in the form YYYY-MM-DD
131 if (from.size() != 10 || from[4] != '-' || from[7] != '-')
132 {
133 this->errorType = "badArgument";
134 params.erase("from");
135 }
136 }
137 // Check the until date is in the correct format: YYYY-MM-DD
138 if (until != "")
139 {
140 // Must be in the form YYYY-MM-DD
141 if (until.size() != 10 || until[4] != '-' || until[7] != '-')
142 {
143 this->errorType = "badArgument";
144 params.erase("until");
145 }
146 }
147
148 if (this->errorType == "badArgument")
149 {
150 return false;
151 }
152
153 // If both arguments are supplied the from date must be less than or equal to the until date
154 if (from != "" && until != "" && !(from <= until))
155 {
156 this->errorType = "badArgument";
157 return false;
158 }
159 }
160
161 // Check "set" argument
162 if (params["set"] != "")
163 {
164 // Example set specification: "demo:CL2"
165 text_t set = params["set"];
166
167 // Is the set a super collection??
168 text_tarray &super_collections = this->configuration->getSuperCollectionsList();
169 bool super_collection_found = false;
170 for (int c = 0; c < super_collections.size(); c++)
171 {
172 if (super_collections[c] == set)
173 {
174 super_collection_found = true;
175 break;
176 }
177 }
178 if (super_collection_found) {
179 this->errorType = "";
180 return true;
181 }
182
183 // Extract the collection name from the set specification
184 text_t collection = "";
185 oaiclassifier::toGSDL(collection, set);
186
187 // Check that the collection is accessible
188 ColInfoResponse_t cinfo;
189 comerror_t err;
190 protocol->get_collectinfo(collection, cinfo, err, cerr);
191 if (err != noError)
192 {
193 this->errorType = "badArgument";
194 return false;
195 }
196
197 // Check the collection is one that is in the list in the oai.cfg file
198 if (!this->configuration->isValidCollection(collection)) {
199 this->errorType = "badArgument";
200 return false;
201 }
202
203 // Check the child set if it was given
204 if (set != "" && !this->check_classifier(protocol, collection, set))
205 {
206 this->errorType = "badArgument";
207 return false;
208 }
209
210 // check we're not requested to retrieve records of *this* set/coll
211 // from an earlier date than *this* set's earliestdatestamp
212 if (params["until"] != "") {
213 text_t eDatestamp = cinfo.earliestDatestamp;
214 time_t raw_time = (time_t)eDatestamp.getint();
215 eDatestamp = this->parseDatestamp(raw_time);
216
217 // error if request is for records of an earlier date than this coll/set's earliestDatestamp
218 if(params["until"] < eDatestamp) {
219 this->errorType = "noRecordsMatch"; // for *this* set/coll of the repository
220 return false;
221 }
222 }
223
224 } else { // no set (collection) specified
225 if (params ["until"] != "") { // check we're not requested to retrieve records of an earlier
226 // date than the earliestdatestamp across all collections/sets
227 // John Thompson advises not to do lazy evaluation of earliestDatestamp here, because
228 // reading x number of build.cfg files for x number of collections to work out the
229 // earliestDatestamp among them is not too expensive an operation, but we do want the OAI
230 // Server to give accurate results when queried, as that's specified by the OAI protocol.
231 //if(this->mEarliestDatestamp == "") {
232 text_t eDatestamp = this->calcEarliestDatestamp(protocol, params);
233 //}
234
235 if(params["until"] < eDatestamp) { // request is for records of an earlier date than earliestDatestamp
236 this->errorType = "noRecordsMatch";
237 return false;
238 }
239 }
240 }
241
242 // If we've reached here everything must be fine
243 this->errorType = "";
244 return true;
245}
246
247//-----------------------------------------------------------------------------------------------
248
249bool listrecsaction::output_document(ostream &output, recptproto *protocol, const text_t &collection,
250 const text_t &OID, const text_t &metadataPrefix)
251{
252 this->record_action->output_record(output, protocol, collection, OID, metadataPrefix);
253 return true;
254}
255
256//-----------------------------------------------------------------------------------------------
257
258
259
Note: See TracBrowser for help on using the repository browser.