root/main/trunk/greenstone2/runtime-src/src/oaiservr/oaiconfig.cpp @ 22286

Revision 22286, 11.2 KB (checked in by kjdon, 9 years ago)

previous commit message was for a different file. Should have been: added repositoryId and repositoryIdVersion to oai.cfg, so added code to read these in in configure and methods to reqtrieve them. Also added code to configure oaiversion as it was being ignored

  • Property svn:keywords set to Author Date Id Revision
Line 
1#include "oaiconfig.h"
2#include <iostream>
3#include <stdlib.h>
4#include "fileutil.h"
5
6
7/**
8 *  The mapping works as follows in the oai.cfg or collect.cfg file.
9 *
10 *  A line is in the format oaimapping <collection field> <oai field>
11 *
12 *  The map here is used to look up the "Greenstone" name which is mapped from
13 *  a given OAI field name, the reverse direction to that given in the
14 *  Greenstone collect.cfg file.  The oairecordaction class instance which
15 *  produces output for an OAI record information request thus uses the map
16 *  to work from the field in the collection it has on hand which OAI
17 *  record name it should use instead.
18 *
19 *  An extension is to be used for this in which the OAI field name in the
20 *  collect.cfg file can be made specific for a particular record format.
21 *  This is done using the OAI field name in the format of
22 *    <OAI format>.<OAI field name>
23 *  Thus, an rfc1807 Title field would be referred to as rfc1807.Title
24 *
25 *  A collection-level mapping can be provided in oai.cfg by prepending
26 *  collname to collection field:
27 *  <collname:field> <oai field>
28
29 *  In the absence of a particular format name, the mapping is taken to be
30 *  universal.
31 */
32
33oaiconfig::oaiconfig() : configurable () {
34  this->resumptionSize = -1; // Default = do not use resumption tokens
35}
36
37oaiconfig::oaiconfig(text_t &gsdlhome, text_t &gsdlcollect)
38{
39  // read main configuration file (oai.cfg) to get oai collections
40  text_t mainconfig = filename_cat(gsdlhome, "etc", "oai.cfg");
41  this->collection = "";
42  this->resumptionSize = -1;
43  this->read_configfile(mainconfig);
44
45  // then if we've not got a specified collection in the gsdlcollect
46  // parameter, read in all the collection's individual configurations
47  if (gsdlcollect == "") {
48    text_tarray::iterator start = this->collectList.begin();
49    text_tarray::iterator here  = this->collectList.end()-1;
50    while (here != start) {     
51      if (!this->configureCollection(gsdlhome, *here)) {
52    this->collectList.erase(here);
53      }
54      --here;
55    }
56    // and do the first one
57    if (!this->configureCollection(gsdlhome, *here)) {
58      this->collectList.erase(here);
59    }
60   
61  }
62  else {
63    // what do we do if this fails?
64    this->configureCollection(gsdlhome, gsdlcollect);
65  }
66}
67
68oaiconfig::~oaiconfig()
69{
70  oaicollectmap::iterator here = this->collectMap.begin();
71  oaicollectmap::iterator end  = this->collectMap.end();
72  while (here != end) {
73    delete here->second;
74    ++here;
75  }
76}
77
78int oaiconfig::resumeAfter()
79{ return this->resumptionSize;
80}
81
82int oaiconfig::getOAIVersion()
83{
84  if (this->oaiVersion == "1.1") {
85    return 110;
86  }
87  return 200;
88}
89
90bool oaiconfig::configureCollection(const text_t &gsdlhome, const text_t &gsdlcollect)
91{
92  text_t cnfgfile = filename_cat(gsdlhome, "collect", gsdlcollect, "etc", "collect.cfg");
93  if (!file_exists(cnfgfile)) {
94    return false;
95  }
96  this->collection = gsdlcollect;
97  this->read_configfile(cnfgfile);
98
99  return true;
100}
101void oaiconfig::configure (const text_t &key, const text_tarray &cfgline)
102{
103  // we've got an oai mapping item, and at least two fields
104  if (key == "oaimapping" && cfgline.size() > 1) {
105    text_t::const_iterator colonAt;
106    text_t index, name, configCollection;
107
108    // Take a default collection as being whatever the collection being configured is...
109    configCollection = this->collection;
110   
111    // get the name of the (collection) field to map; this may actually
112    // be in a colon separated format of the type
113    // <collection name>:<field name>
114    index = cfgline[0];
115    if ((colonAt = findchar(index.begin(), index.end(), ':')) != index.end()) {
116      configCollection = substr(index.begin(), colonAt);
117
118      if (this->collection != "" && configCollection != this->collection) {
119    cerr << "Attempt to configure OAI mappings for " << configCollection << " in " << this->collection << endl;
120      }
121
122      colonAt += 1;
123      index = substr(colonAt, index.end());
124    }
125   
126    // the second parameter is the metadata field to map the collection
127    // field onto.  It may be provided with a metadata protocol (which
128    // will be given first and separated by a period or full stop).  In
129    // the case of format.field name, the splitting is done here.
130    if ((colonAt = findchar(cfgline[1].begin(), cfgline[1].end(), '.')) != cfgline[1].end()) {
131      text_t stub = substr(cfgline[1].begin(), colonAt);
132      colonAt += 1;
133      name = substr(colonAt, cfgline[1].end());
134      index.append(":");
135      index.append(stub);
136    }
137    else {
138      name = cfgline[1];
139    }
140   
141    // now 'index' is in the form <collectionfield>:(formatname)
142    //     'name' is simply the fieldname within the format
143    //     'configCollection' is the collection to be configured
144   
145    // now simply map the field name (index) onto the collection name (name)
146    if (this->collectMap[configCollection] == NULL) {
147      this->collectMap[configCollection] = new oaicollectconfig(configCollection);
148    }
149    this->collectMap[configCollection]->fieldMap[index] = name;
150   
151    //    cerr << "Mapping " << index << " to " << name << " in " << configCollection << endl;
152   
153    // TODO: check that the mapped field is actually in use
154  }
155  else if (key == "oaicollection" && cfgline.size() >= 1) {
156    // Configure a collection to be used as part of the OAI archive.
157    // This line should read:
158    //
159    // oaicollection <collectionname>
160    //
161    // Where <collectionname> is the name of the directory inside the
162    // gsdl/collect folder which contains the collection.
163    //
164    // To configure several collections, merely repeat this line,
165    // or alternatively use additional collection names after the
166    // first one.
167    //
168    // This configuration should only appear in oai.cfg
169    //
170    if (this->collection != "") {
171      cerr << "Attempt to configure an oai collection outside of oai.cfg" << endl;
172      cerr << "Configuration attempted in " << this->collection << " collection." << endl;
173      exit(1);
174    }
175    for (int c = 0; c < cfgline.size(); ++c) {
176      this->collectList.push_back(cfgline[c]);
177    }
178  }
179  else if (key == "oaimetadata" && cfgline.size() >= 1) {
180    // List of metadata prefixes to suuport
181    // This line should read:
182    //
183    // oaicollection <metadataname> <metadataname>...
184    //
185    //
186    // This configuration should only appear in oai.cfg
187    //
188    if (this->collection != "") {
189      cerr << "Attempt to configure oai metadata outside of oai.cfg" << endl;
190      cerr << "Configuration attempted in " << this->collection << " collection." << endl;
191      exit(1);
192    }
193    for (int c = 0; c < cfgline.size(); ++c) {
194      // todo: check that the set name is valid
195      this->metadataSet.insert(cfgline[c]);
196    }
197  }
198  else if (key == "oaiinfo" && cfgline.size() >= 1) {
199    // Get a piece of information for the oai repository information
200    // request.  The line should read:
201    //
202    // oaiinfo <information field name> <value>
203    //
204    // This configuration should only be attempted in oai.cfg
205    //
206    if (this->collection != "") {
207      cerr << "Attempt to set oai information outside of oai.cfg" << endl;
208      cerr << "Configuration attempted in " << this->collection << " collection." << endl;
209      exit(1);
210    }
211   
212    // if no second parameter is given, then the first parameter
213    if (cfgline.size() == 1) {
214      this->infoMap[cfgline[0]] = cfgline[0];
215    }
216    else {
217      this->infoMap[cfgline[0]] = cfgline[1];
218    }
219  }
220  else if ( key == "oaisetname" || key == "oaisetdescription") {
221    text_t coll_name;
222    text_t value = "";
223    if (this->collection != "") {
224      // we are in collect.cfg
225      coll_name = this->collection;
226      if (cfgline.size() == 1) {
227    // just the collection value
228    value = cfgline[0];
229      }
230      else if (cfgline.size() == 2) {
231    // we have a subset name (eg for classifier)
232    coll_name.append(":");
233    coll_name.append(cfgline[0]);
234    value = cfgline[1];
235      }
236    } else if (cfgline.size() == 2) {
237      // oai.cfg, line should be collname, setName
238      coll_name = cfgline[0];
239      value = cfgline[1];
240    }
241    if (value != "") {
242      if (this->collectMap[coll_name] == NULL) {
243    this->collectMap[coll_name] = new oaicollectconfig(coll_name);
244      }
245      if (key == "oaisetname") {
246    this->collectMap[coll_name]->setName = value;
247      } else if (key == "oaisetdescription") {
248    this->collectMap[coll_name]->setDescription = value;
249      }
250    }
251  }
252
253  else if (key == "resumeafter" && cfgline.size() >= 1) {
254    this->resumptionSize = cfgline[0].getint();
255  }
256
257  else if (key == "maintainer") {
258    this->maintainer = cfgline[0];
259  }
260  else if (key == "repositoryName") {
261    this->repositoryName = cfgline[0];
262  }
263  else if (key == "repositoryId") {
264    this->repositoryId = cfgline[0];
265  }
266  else if (key == "repositoryIdVersion") {
267    this->repositoryIdVersion = cfgline[0];
268  }
269  else if (key == "baseURL") {
270    this->baseURL = cfgline[0];
271  }
272  else if (key == "baseLibraryURL") {
273    this->baseLibraryURL = cfgline[0];
274  }
275  else if (key == "baseDocRoot") {
276    this->baseDocRoot = cfgline[0];
277  }
278  else if (key == "oaiversion") {
279    this->oaiVersion = cfgline[0];
280  }
281 
282}
283
284text_t oaiconfig::getMapping(const text_t &collection, const text_t &collectfield)
285{
286  if (this->collectMap[collection] == NULL) {
287    return "";
288  }
289  return this->collectMap[collection]->fieldMap[collectfield];
290}
291
292/**
293 *  Get the mapping for a field in a given collection; if no mapping
294 *  exists, the result will be a blank string.
295 */
296text_t oaiconfig::getMapping(const text_t &collection, const text_t &collectfield, const text_t &formatname)
297{
298  text_t fullName = collectfield;
299  fullName.append(":");
300  fullName.append(formatname);
301
302  // try the collection-specific options first
303  if (this->collectMap[collection] != NULL) {
304    // first try the most specific item - this collection, and given that protocol
305    if (this->collectMap[collection]->fieldMap.count(fullName) >= 1) {
306      return this->collectMap[collection]->fieldMap[fullName];
307    }
308    // otherwise, fall back to this collection, and all protocols
309    else if (this->collectMap[collection]->fieldMap.count(collectfield) >= 1) {
310      return this->collectMap[collection]->fieldMap[collectfield];
311    }
312  }
313
314  // if no mappings exist, return an empty item
315  if (this->collectMap[""] == NULL) {
316    return "";
317  }
318
319  // then try generic rules
320  if (this->collectMap[""]->fieldMap.count(fullName) >= 1) {
321    return this->collectMap[""]->fieldMap[fullName];
322  }
323  else {
324    return this->collectMap[""]->fieldMap[collectfield];
325  }
326}
327
328text_t oaiconfig::getBaseURL()
329{
330  return this->baseURL;
331}
332text_t oaiconfig::getBaseLibraryURL()
333{
334  return this->baseLibraryURL;
335}
336text_t oaiconfig::getBaseDocRoot()
337{
338  return this->baseDocRoot;
339}
340text_t oaiconfig::getRepositoryName()
341{
342  return this->repositoryName;
343}
344text_t oaiconfig::getRepositoryId()
345{
346  return this->repositoryId;
347}
348text_t oaiconfig::getRepositoryIdVersion()
349{
350  return this->repositoryIdVersion;
351}
352text_t oaiconfig::getMaintainer()
353{
354  return this->maintainer;
355}
356text_t oaiconfig::getSetName(const text_t &setSpec)
357{
358  if (this->collectMap[setSpec] == NULL) {
359    return "" ;
360  }
361 
362  return this->collectMap[setSpec]->setName;
363 
364}
365
366text_t oaiconfig::getSetDescription(const text_t &setSpec)
367{
368  if (this->collectMap[setSpec] == NULL) {
369    return "" ;
370  }
371 
372  return this->collectMap[setSpec]->setDescription;
373}
374
Note: See TracBrowser for help on using the browser.