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

Last change on this file since 22286 was 22286, checked in by kjdon, 14 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
File size: 11.2 KB
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 repository browser.