source: main/trunk/greenstone2/runtime-src/src/oaiservr/recordaction.cpp@ 24286

Last change on this file since 24286 was 24286, checked in by ak19, 13 years ago

John Rose and Luigi had identified a bug in the Resource Identifier URLs served upon a GetRecord action (the same metadata field served by a ListRecords action was not faulty). The URL contained the incorrect name for the collection. As it happens, some previous code committed in commented out form with this file did have the necessary fix, however, as it was embedded in a OAI ID test that need not get executed in this stage of the code, the code crucially correcting the URL's collection name was also commented out as a result. Reinstating only the necessary line that adjusts the URL's collection name.

  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1/**********************************************************************
2 *
3 * recordaction.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 "recordaction.h"
28#include "recptprototools.h"
29#include "dublincore.h"
30#include "qualified_dublincore.h"
31#include "rfc1807.h"
32#include "oaitools.h"
33
34
35recordaction::recordaction(text_tset &metadataset) : oaiaction("GetRecord") {
36 metaformatptr fptr;
37
38 if (metadataset.count("oai_dc") > 0) {
39 fptr.set_class(new dublin_core());
40 this->formatMap[fptr.get_class()->formatName()] = fptr;
41 }
42
43 if (metadataset.count("gsdl_qdc") > 0) {
44 fptr.set_class(new qualified_dublin_core());
45 this->formatMap[fptr.get_class()->formatName()] = fptr;
46 }
47
48 if (metadataset.count("rfc1807") > 0) {
49
50 fptr.set_class(new rfc1807());
51 this->formatMap[fptr.get_class()->formatName()] = fptr;
52 }
53}
54
55recordaction::~recordaction() {
56 metaformat_map::iterator here = this->formatMap.begin();
57 metaformat_map::iterator end = this->formatMap.end();
58
59 while (here != end) {
60 here->second.clear();
61 ++here;
62 }
63}
64
65
66bool recordaction::validateAction(recptproto *protocol, oaiargs &params)
67{
68 // ----------------------------------------------------------------------------
69 // 1. Check for invalid arguments
70 // ----------------------------------------------------------------------------
71 bool invalid_argument_supplied = false;
72 text_tmap::const_iterator param_iterator = params.begin();
73 while (param_iterator != params.end())
74 {
75 // Check for arguments that aren't valid for this action
76 if (param_iterator->first != "verb" &&
77 param_iterator->first != "identifier" &&
78 param_iterator->first != "metadataPrefix")
79 {
80 // We've found an invalid argument
81 invalid_argument_supplied = true;
82
83 // Delete the invalid argument from the list so it doesn't end up in the <request> tag that is returned
84 params.erase(param_iterator->first);
85 }
86
87 param_iterator++;
88 }
89
90 // If we found an invalid argument it's an error, so don't go any further
91 if (invalid_argument_supplied)
92 {
93 this->errorType = "badArgument";
94 return false;
95 }
96
97 // ----------------------------------------------------------------------------
98 // 2. Handle any exclusive arguments
99 // ----------------------------------------------------------------------------
100
101 // None!
102
103 // ----------------------------------------------------------------------------
104 // 3. Handle any required arguments
105 // ----------------------------------------------------------------------------
106
107 // The "metadataPrefix" argument is required
108 text_t metadataPrefix = params["metadataPrefix"];
109
110 // Check that the metadataPrefix argument exists
111 if (metadataPrefix == "")
112 {
113 this->errorType = "badArgument";
114 return false;
115 }
116
117 // Check that the metadataPrefix is a format we support
118 if (this->formatNotSupported(metadataPrefix))
119 {
120 this->errorType = "cannotDisseminateFormat";
121 return false;
122 }
123
124 // The "identifier" argument is required
125 text_t identifier = params["identifier"];
126
127 // Check that the identifier argument exists
128 if (identifier == "")
129 {
130 this->errorType = "badArgument";
131 return false;
132 }
133
134 // before checking the specified identifier exists, need to extract the greenstone OID from it
135 text_t oai_OID_prefix = "oai:"+this->configuration->getRepositoryId()+":";
136 if(identifier.replace(oai_OID_prefix, "") <= 0) {
137 this->errorType = "idDoesNotExist";
138 // Only throw an error if we're using v2.0.
139 if (this->configuration->getOAIVersion() >= 200) {
140 return false;
141 }
142 }
143
144 // Extract the collection name from the identifier specification
145 text_t collection = "";
146 oaiclassifier::toGSDL(collection, identifier);
147
148 // Check a document with the specified identifier exists
149 text_tset metadata;
150 if (!get_info(identifier, collection, "", metadata, false, protocol, this->gsdlResponse, *logout))
151 {
152 this->errorType = "idDoesNotExist";
153 return false;
154 }
155
156 // ----------------------------------------------------------------------------
157 // 4. Check any remaining arguments
158 // ----------------------------------------------------------------------------
159
160 // None!
161
162 // If we've reached here everything must be fine
163 this->errorType = "";
164 return true;
165}
166
167//
168// Output the content of a GetRecord request; in this case, the static member
169// output_record below is used to fulfill most of the request
170//
171bool recordaction::output_content(ostream &output, recptproto *protocol, oaiargs &params)
172{
173 // validateAction will already have set up the correct response content
174 text_t gsdlId = params["identifier"];
175 text_t gsdlCollect;
176
177 // although at this stage, we don't actually need to be testing that the identifier exists
178 // (this method is not meant to throw an idDoesNotExist error), we do however need to be
179 // working with the correct identifier, so we need to remove any oai_OID_prefix from the
180 // gsdlId in order to extract the greenstone OID.
181 text_t oai_OID_prefix = "oai:"+this->configuration->getRepositoryId()+":";
182 gsdlId.replace(oai_OID_prefix, "");
183
184 // convert record identifier into GSDL format from OAI
185 oaiclassifier::toGSDL(gsdlCollect, gsdlId);
186
187 // go direct to output_record
188 return output_record(output, gsdlCollect, gsdlId, params["metadataPrefix"]);
189}
190
191//
192// A static member that does everything the output_content method above needs,
193// but can be called when individual records are being output for another
194// action.
195//
196bool recordaction::output_record(ostream &output, recptproto *protocol, const text_t &collection, const text_t &OID, const text_t &metadataPrefix)
197{
198 text_tset metadata;
199 ofstream logout("oai.log", ios::app);
200
201 // get the document information
202 if (!get_info(OID, collection, "", metadata, false, protocol, this->gsdlResponse, logout)) {
203
204 this->errorType = "idDoesNotExist";
205
206 if(this->configuration->getOAIVersion() >= 200) {
207 this->output_error(output, errorType);
208 return false;
209 }
210 }
211
212 return this->output_record(output, collection, OID, metadataPrefix);
213}
214
215bool recordaction::output_record(ostream &output, const text_t &collection, const text_t &OID,
216 const text_t &metadataPrefix)
217{ int oaiVersion = this->configuration->getOAIVersion();
218
219 // check to see if it's a classifier
220 text_t childHead;
221 text_t::const_iterator start = OID.begin();
222 text_t::const_iterator here = OID.begin();
223 here += 2;
224 childHead = substr(start, here);
225
226 // if it isn't a document, kill it now
227 if (childHead == "CL") {
228 cerr << "Not a document" << endl;
229 return false;
230 }
231
232 ResultDocInfo_t doc_info = this->gsdlResponse.docInfo[0];
233 text_t lastModified = "";
234
235 // Fills lastModified with the date from the document in doc_info, in the format YYYY-MM-DD
236 this->getLastModifiedDate(doc_info, lastModified);
237
238 // If the ID exists, output record for oai response (OAI v1.1)
239 // OAI v2.0 will already have bailed if ID doesn't exist (yes?)
240 if (this->errorType != "idDoesNotExist") {
241 text_t oaiLabel = OID;
242 oaiclassifier::toOAI(this->configuration->getRepositoryId(), collection, oaiLabel); // Concatenates HASH id to collection, which OAI needs
243
244 // output a record
245 output << " <record>\n";
246
247 // output header part of oai response
248 this->output_record_header(output, oaiLabel, lastModified,
249 doc_info.metadata["memberof"].values, oaiVersion);
250
251 if (this->errorType != "cannotDisseminateFormat"){
252 if (this->formatMap[metadataPrefix].get_class()->output_metadata(output, collection, doc_info)) {
253 // output 'about' part of oai response - we probably won't ever use this
254 //output << " <about>\n";
255 //output << " </about>\n";
256 }
257 }
258 // close record
259 output << " </record>\n\n";
260 }
261 return true;
262}
Note: See TracBrowser for help on using the repository browser.