source: gsdl/trunk/src/oaiservr/recordaction.cpp@ 15198

Last change on this file since 15198 was 15198, checked in by mdewsnip, 16 years ago

Now each action checks for invalid arguments in the params structure and deletes any that aren't valid, so they don't get into the "<request>" tag in the resulting XML and cause OAI validation errors. By DL Consulting Ltd.

  • Property svn:keywords set to Author Date Id Revision
File size: 5.1 KB
Line 
1#include "recordaction.h"
2#include "OIDtools.h"
3#include "dublincore.h"
4#include "rfc1807.h"
5#include "oaitools.h"
6#include <time.h>
7
8
9recordaction::recordaction() : oaiaction("GetRecord") {
10 metaformatptr fptr;
11
12 fptr.set_class(new dublin_core());
13 this->formatMap[fptr.get_class()->formatName()] = fptr;
14
15 fptr.set_class(new rfc1807());
16 this->formatMap[fptr.get_class()->formatName()] = fptr;
17}
18
19recordaction::~recordaction() {
20 metaformat_map::iterator here = this->formatMap.begin();
21 metaformat_map::iterator end = this->formatMap.end();
22
23 while (here != end) {
24 here->second.clear();
25 ++here;
26 }
27}
28
29
30bool recordaction::validateAction(recptproto *protocol, oaiargs &params)
31{
32 int params_size = params.getSize();
33
34 // Remove any parameters that aren't valid for this action
35 text_tmap::const_iterator param_iterator = params.begin();
36 while (param_iterator != params.end())
37 {
38 if (param_iterator->first != "verb" &&
39 param_iterator->first != "identifier" &&
40 param_iterator->first != "metadataPrefix")
41 {
42 params.erase(param_iterator->first);
43 }
44
45 param_iterator++;
46 }
47
48 text_t meta = params["metadataPrefix"];
49 text_t gsdlId = params["identifier"];
50 text_t gsdlCollect;
51 text_t language = "";
52 int oaiVersion = this->configuration->getOAIVersion();
53
54 // The identifier and metadataPrefix args MUST be supplied, and are the only
55 // args allowed (excluding verb arg). If we don't have them, throw an error.
56 if(gsdlId == "" || meta == "" || params_size != 3){
57 this->errorType = "badArgument";
58 return false;
59 }
60
61 // Check to see if the metadataPrefix supplied is supported
62 if(this->formatNotSupported(meta)) {
63 this->errorType = "cannotDisseminateFormat";
64 if(oaiVersion == 200)
65 return false;
66 }
67
68 // convert record identifier into GSDL format from OAI
69 oaiclassifier::toGSDL(gsdlCollect, gsdlId);
70
71 // get the document information
72 text_tset metadata;
73 if (!get_info(gsdlId, gsdlCollect, language, metadata, false, protocol, this->gsdlResponse, *logout)) {
74 this->errorType = "idDoesNotExist";
75 if(oaiVersion == 200)
76 return false;
77 }
78
79 return true;
80}
81
82//
83// Output the content of a GetRecord request; in this case, the static member
84// output_record below is used to fulfill most of the request
85//
86bool recordaction::output_content(ostream &output, recptproto *protocol, oaiargs &params)
87{
88 // validateAction will already have set up the correct response content
89 text_t gsdlId = params["identifier"];
90 text_t gsdlCollect;
91
92 // convert record identifier into GSDL format from OAI
93 oaiclassifier::toGSDL(gsdlCollect, gsdlId);
94
95 // go direct to output_record
96 return output_record(output, gsdlCollect, gsdlId, params["metadataPrefix"]);
97}
98
99//
100// A static member that does everything the output_content method above needs,
101// but can be called when individual records are being output for another
102// action.
103//
104bool recordaction::output_record(ostream &output, recptproto *protocol, const text_t &collection, const text_t &OID, const text_t &metadataPrefix)
105{
106 text_tset metadata;
107 ofstream logout("oai.log", ios::app);
108
109 // get the document information
110 if (!get_info(OID, collection, "", metadata, false, protocol, this->gsdlResponse, logout)) {
111
112 this->errorType = "idDoesNotExist";
113
114 if(this->configuration->getOAIVersion() >= 200) {
115 this->output_error(output, errorType);
116 return false;
117 }
118 }
119
120 return this->output_record(output, collection, OID, metadataPrefix);
121}
122
123bool recordaction::output_record(ostream &output, const text_t &collection, const text_t &OID,
124 const text_t &metadataPrefix)
125{ int oaiVersion = this->configuration->getOAIVersion();
126
127 // check to see if it's a classifier
128 text_t childHead;
129 text_t::const_iterator start = OID.begin();
130 text_t::const_iterator here = OID.begin();
131 here += 2;
132 childHead = substr(start, here);
133
134 // if it isn't a document, kill it now
135 if (childHead == "CL") {
136 cerr << "Not a document" << endl;
137 return false;
138 }
139
140 ResultDocInfo_t doc_info = this->gsdlResponse.docInfo[0];
141 text_t lastModified = "";
142
143 // Fills lastModified with the date from the document in doc_info, in the format YYYY-MM-DD
144 this->getLastModifiedDate(doc_info, lastModified);
145
146 // If the ID exists, output record for oai response (OAI v1.1)
147 // OAI v2.0 will already have bailed if ID doesn't exist (yes?)
148 if (this->errorType != "idDoesNotExist") {
149 text_t oaiLabel = OID;
150 oaiclassifier::toOAI(collection, oaiLabel); // Concatenates HASH id to collection, which OAI needs
151
152 // output a record
153 output << " <record>\n";
154
155 // output header part of oai response
156 this->output_record_header(output, oaiLabel, lastModified,
157 doc_info.metadata["memberof"].values, oaiVersion);
158
159 if (this->errorType != "cannotDisseminateFormat"){
160 if (this->formatMap[metadataPrefix].get_class()->output_metadata(output, collection, doc_info)) {
161 // output 'about' part of oai response - we probably won't ever use this
162 //output << " <about>\n";
163 //output << " </about>\n";
164 }
165 }
166 // close record
167 output << " </record>\n\n";
168 }
169 return true;
170}
Note: See TracBrowser for help on using the repository browser.