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

Revision 22212, 10.8 KB (checked in by kjdon, 10 years ago)

tidied up the config classes. moved all the global params into oaiconfig instead of having them in the collection map. put setname and description into the collection map instead of having their own maps. Added methods to access baseURL etc

  • 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 == "baseURL") {
264    this->baseURL = cfgline[0];
265  }
266  else if (key == "baseLibraryURL") {
267    this->baseLibraryURL = cfgline[0];
268  }
269  else if (key == "baseDocRoot") {
270    this->baseDocRoot = cfgline[0];
271  }
272 
273}
274
275
276text_t oaiconfig::getMapping(const text_t &collection, const text_t &collectfield)
277{
278  if (this->collectMap[collection] == NULL) {
279    return "";
280  }
281  return this->collectMap[collection]->fieldMap[collectfield];
282}
283
284/**
285 *  Get the mapping for a field in a given collection; if no mapping
286 *  exists, the result will be a blank string.
287 */
288text_t oaiconfig::getMapping(const text_t &collection, const text_t &collectfield, const text_t &formatname)
289{
290  text_t fullName = collectfield;
291  fullName.append(":");
292  fullName.append(formatname);
293
294  // try the collection-specific options first
295  if (this->collectMap[collection] != NULL) {
296    // first try the most specific item - this collection, and given that protocol
297    if (this->collectMap[collection]->fieldMap.count(fullName) >= 1) {
298      return this->collectMap[collection]->fieldMap[fullName];
299    }
300    // otherwise, fall back to this collection, and all protocols
301    else if (this->collectMap[collection]->fieldMap.count(collectfield) >= 1) {
302      return this->collectMap[collection]->fieldMap[collectfield];
303    }
304  }
305
306  // if no mappings exist, return an empty item
307  if (this->collectMap[""] == NULL) {
308    return "";
309  }
310
311  // then try generic rules
312  if (this->collectMap[""]->fieldMap.count(fullName) >= 1) {
313    return this->collectMap[""]->fieldMap[fullName];
314  }
315  else {
316    return this->collectMap[""]->fieldMap[collectfield];
317  }
318}
319
320text_t oaiconfig::getBaseURL()
321{
322  return this->baseURL;
323}
324text_t oaiconfig::getBaseLibraryURL()
325{
326  return this->baseLibraryURL;
327}
328text_t oaiconfig::getBaseDocRoot()
329{
330  return this->baseDocRoot;
331}
332text_t oaiconfig::getRepositoryName()
333{
334  return this->repositoryName;
335}
336text_t oaiconfig::getMaintainer()
337{
338  return this->maintainer;
339}
340text_t oaiconfig::getSetName(const text_t &setSpec)
341{
342  if (this->collectMap[setSpec] == NULL) {
343    return "" ;
344  }
345 
346  return this->collectMap[setSpec]->setName;
347 
348}
349
350text_t oaiconfig::getSetDescription(const text_t &setSpec)
351{
352  if (this->collectMap[setSpec] == NULL) {
353    return "" ;
354  }
355 
356  return this->collectMap[setSpec]->setDescription;
357}
358
Note: See TracBrowser for help on using the browser.