#include "recordaction.h" #include "recptprototools.h" #include "dublincore.h" #include "qualified_dublincore.h" #include "rfc1807.h" #include "oaitools.h" recordaction::recordaction(text_tset &metadataset) : oaiaction("GetRecord") { metaformatptr fptr; if (metadataset.count("oai_dc") > 0) { fptr.set_class(new dublin_core()); this->formatMap[fptr.get_class()->formatName()] = fptr; } if (metadataset.count("gsdl_qdc") > 0) { fptr.set_class(new qualified_dublin_core()); this->formatMap[fptr.get_class()->formatName()] = fptr; } if (metadataset.count("rfc1807") > 0) { fptr.set_class(new rfc1807()); this->formatMap[fptr.get_class()->formatName()] = fptr; } } recordaction::~recordaction() { metaformat_map::iterator here = this->formatMap.begin(); metaformat_map::iterator end = this->formatMap.end(); while (here != end) { here->second.clear(); ++here; } } bool recordaction::validateAction(recptproto *protocol, oaiargs ¶ms) { // ---------------------------------------------------------------------------- // 1. Check for invalid arguments // ---------------------------------------------------------------------------- bool invalid_argument_supplied = false; text_tmap::const_iterator param_iterator = params.begin(); while (param_iterator != params.end()) { // Check for arguments that aren't valid for this action if (param_iterator->first != "verb" && param_iterator->first != "identifier" && param_iterator->first != "metadataPrefix") { // We've found an invalid argument invalid_argument_supplied = true; // Delete the invalid argument from the list so it doesn't end up in the tag that is returned params.erase(param_iterator->first); } param_iterator++; } // If we found an invalid argument it's an error, so don't go any further if (invalid_argument_supplied) { this->errorType = "badArgument"; return false; } // ---------------------------------------------------------------------------- // 2. Handle any exclusive arguments // ---------------------------------------------------------------------------- // None! // ---------------------------------------------------------------------------- // 3. Handle any required arguments // ---------------------------------------------------------------------------- // The "metadataPrefix" argument is required text_t metadataPrefix = params["metadataPrefix"]; // Check that the metadataPrefix argument exists if (metadataPrefix == "") { this->errorType = "badArgument"; return false; } // Check that the metadataPrefix is a format we support if (this->formatNotSupported(metadataPrefix)) { this->errorType = "cannotDisseminateFormat"; return false; } // The "identifier" argument is required text_t identifier = params["identifier"]; // Check that the identifier argument exists if (identifier == "") { this->errorType = "badArgument"; return false; } // Extract the collection name from the identifier specification text_t collection = ""; oaiclassifier::toGSDL(collection, identifier); // Check a document with the specified identifier exists text_tset metadata; if (!get_info(identifier, collection, "", metadata, false, protocol, this->gsdlResponse, *logout)) { this->errorType = "idDoesNotExist"; return false; } // ---------------------------------------------------------------------------- // 4. Check any remaining arguments // ---------------------------------------------------------------------------- // None! // If we've reached here everything must be fine this->errorType = ""; return true; } // // Output the content of a GetRecord request; in this case, the static member // output_record below is used to fulfill most of the request // bool recordaction::output_content(ostream &output, recptproto *protocol, oaiargs ¶ms) { // validateAction will already have set up the correct response content text_t gsdlId = params["identifier"]; text_t gsdlCollect; // convert record identifier into GSDL format from OAI oaiclassifier::toGSDL(gsdlCollect, gsdlId); // go direct to output_record return output_record(output, gsdlCollect, gsdlId, params["metadataPrefix"]); } // // A static member that does everything the output_content method above needs, // but can be called when individual records are being output for another // action. // bool recordaction::output_record(ostream &output, recptproto *protocol, const text_t &collection, const text_t &OID, const text_t &metadataPrefix) { text_tset metadata; ofstream logout("oai.log", ios::app); // get the document information if (!get_info(OID, collection, "", metadata, false, protocol, this->gsdlResponse, logout)) { this->errorType = "idDoesNotExist"; if(this->configuration->getOAIVersion() >= 200) { this->output_error(output, errorType); return false; } } return this->output_record(output, collection, OID, metadataPrefix); } bool recordaction::output_record(ostream &output, const text_t &collection, const text_t &OID, const text_t &metadataPrefix) { int oaiVersion = this->configuration->getOAIVersion(); // check to see if it's a classifier text_t childHead; text_t::const_iterator start = OID.begin(); text_t::const_iterator here = OID.begin(); here += 2; childHead = substr(start, here); // if it isn't a document, kill it now if (childHead == "CL") { cerr << "Not a document" << endl; return false; } ResultDocInfo_t doc_info = this->gsdlResponse.docInfo[0]; text_t lastModified = ""; // Fills lastModified with the date from the document in doc_info, in the format YYYY-MM-DD this->getLastModifiedDate(doc_info, lastModified); // If the ID exists, output record for oai response (OAI v1.1) // OAI v2.0 will already have bailed if ID doesn't exist (yes?) if (this->errorType != "idDoesNotExist") { text_t oaiLabel = OID; oaiclassifier::toOAI(collection, oaiLabel); // Concatenates HASH id to collection, which OAI needs // output a record output << " \n"; // output header part of oai response this->output_record_header(output, oaiLabel, lastModified, doc_info.metadata["memberof"].values, oaiVersion); if (this->errorType != "cannotDisseminateFormat"){ if (this->formatMap[metadataPrefix].get_class()->output_metadata(output, collection, doc_info)) { // output 'about' part of oai response - we probably won't ever use this //output << " \n"; //output << " \n"; } } // close record output << " \n\n"; } return true; }