source: trunk/gsdl/src/oaiservr/oaiconfig.cpp@ 8182

Last change on this file since 8182 was 8182, checked in by cs025, 20 years ago

Added OAI Server code to Greenstone

  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1#include "oaiconfig.h"
2
3#include <algorithm>
4#include <iostream>
5
6#include "fileutil.h"
7
8/**
9 * The mapping works as follows in the collect.cfg file.
10 *
11 * A line is in the format oaimapping <collection field> <oai field>
12 *
13 * The map here is used to look up the "Greenstone" name which is mapped from
14 * a given OAI field name, the reverse direction to that given in the
15 * Greenstone collect.cfg file. The oairecordaction class instance which
16 * produces output for an OAI record information request thus uses the map
17 * to work from the field in the collection it has on hand which OAI
18 * record name it should use instead.
19 *
20 * An extension is to be used for this in which the OAI field name in the
21 * collect.cfg file can be made specific for a particular record format.
22 * This is done using the OAI field name in the format of
23 * <OAI format>:<OAI field name>
24 * Thus, an rfc1807 Title field would be referred to as rfc1807:Title
25 *
26 * A collection-level mapping is not needed - to configure the behaviour
27 * of a collection, ensure that you place the appropriate configuration in
28 * its etc/collect.cfg file - the oaimapping stuff IS NOT picked up from
29 * the central main.cfg file at the moment.
30 *
31 * In the absence of a particular format name, the mapping is taken to be
32 * universal.
33 */
34
35oaiconfig::oaiconfig() : configurable () {
36}
37
38oaiconfig::oaiconfig(text_t &gsdlhome, text_t &gsdlcollect)
39{
40 // read main configuration file to get oai collections
41 text_t mainconfig = filename_cat(gsdlhome, "etc", "main.cfg");
42 this->collection = "";
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_tset::iterator here = this->collectList.begin();
49 text_tset::iterator end = this->collectList.end();
50 while (here != end) {
51 this->configureCollection(gsdlhome, *here);
52 here ++;
53 }
54 }
55 else {
56 this->configureCollection(gsdlhome, gsdlcollect);
57 }
58}
59
60oaiconfig::~oaiconfig()
61{
62 oaicollectmap::iterator here = this->collectMap.begin();
63 oaicollectmap::iterator end = this->collectMap.end();
64 while (here != end) {
65 delete here->second;
66 here ++;
67 }
68}
69
70int oaiconfig::getOAIVersion()
71{
72 if (this->oaiVersion == "1.1") {
73 return 110;
74 }
75 return 200;
76}
77
78void oaiconfig::configureCollection(const text_t &gsdlhome, const text_t &gsdlcollect)
79{
80 text_t cnfgfile = filename_cat(gsdlhome, "collect", gsdlcollect, "etc", "collect.cfg");
81 this->collection = gsdlcollect;
82 this->read_configfile(cnfgfile);
83}
84
85void oaiconfig::configure (const text_t &key, const text_tarray &cfgline)
86{
87 // we've got an oai mapping item, and at least two fields
88 if (key == "oaimapping" && cfgline.size() > 1) {
89 text_t::const_iterator colonAt;
90 text_t index, name;
91
92 // get the name of the (collection) field to map; this may actually
93 // be in a colon separated format of the type
94 // <collection name>:<field name>
95 index = cfgline[0];
96
97 // the second parameter is the metadata field to map the collection
98 // field onto. It may be provided with a metadata protocol (which
99 // will be given first and separated by a colon). In the case of
100 // format:field name, the splitting is done here.
101 if ((colonAt = find(cfgline[1].begin(), cfgline[1].end(), ':')) != cfgline[1].end()) {
102 text_t stub = substr(cfgline[1].begin(), colonAt);
103 colonAt += 1;
104 name = substr(colonAt, cfgline[1].end());
105 index.append(":");
106 index.append(stub);
107 }
108 else {
109 name = cfgline[1];
110 }
111
112 // now 'index' is in the form:
113 // (collection):<collectionfield>:(formatname) and name is
114 // simply formatfieldname
115
116 // now simply map the field name (index) onto the collection name (name)
117 if (this->collectMap[this->collection] == NULL) {
118 this->collectMap[this->collection] = new oaicollectconfig(this->collection);
119 }
120 this->collectMap[this->collection]->fieldMap[index] = name;
121
122 // cerr << "Mapping " << index << " to " << name << " in " << this->collection << endl;
123
124 // TODO: check that the mapped field is actually in use
125 }
126 else if (key == "oaicollection" && cfgline.size() > 1) {
127 // Configure a collection to be used as part of the OAI archive.
128 // This line should read:
129 //
130 // oaicollection <collectionname>
131 //
132 // Where <collectionname> is the name of the directory inside the
133 // gsdl/collect folder which contains the collection.
134 //
135 // To configure several collections, merely repeat this line,
136 // or alternatively use additional collection names after the
137 // first one.
138 //
139 // This configuration should only appear in main.cfg
140 //
141 if (this->collection != "") {
142 cerr << "Attempt to configure an oai collection outside of main.cfg" << endl;
143 cerr << "Configuration attempted in " << this->collection << " collection." << endl;
144 exit(1);
145 }
146 for (int c = 0; c < cfgline.size(); c ++) {
147 this->collectList.insert(cfgline[c]);
148 }
149 }
150 else if (key == "oaiinfo" && cfgline.size() >= 1) {
151 // Get a piece of information for the oai repository information
152 // request. The line should read:
153 //
154 // oaiinfo <information field name> <value>
155 //
156 // This configuration should only be attempted in main.cfg
157 //
158 if (this->collection != "") {
159 cerr << "Attempt to set oai information outside of main.cfg" << endl;
160 cerr << "Configuration attempted in " << this->collection << " collection." << endl;
161 exit(1);
162 }
163
164 // if no second parameter is given, then the first parameter
165 if (cfgline.size() == 1) {
166 this->infoMap[cfgline[0]] = cfgline[0];
167 }
168 else {
169 this->infoMap[cfgline[0]] = cfgline[1];
170 }
171 }
172 else if (key == "oaiversion" && cfgline.size() >= 1) {
173 this->oaiVersion = cfgline[0];
174 }
175 // get and note a maintainer item to support the Identify Verb of OAI
176 else if (key == "maintainer" && cfgline.size() >= 1) {
177 int line = 0;
178
179 // TODO: exhaustive checks for empty or default values of maintainer
180 while (line < cfgline.size()) {
181 if (cfgline[line] != "NULL" &&
182 cfgline[line] != "") {
183 // do something
184 break;
185 }
186 else {
187 line ++;
188 }
189 }
190
191 // Only try to set the configuration if we have a legitimate value ...
192 if (line < cfgline.size()) {
193 // ensure we have a map to write to
194 if (this->collectMap[this->collection] == NULL) {
195 this->collectMap[this->collection] = new oaicollectconfig(this->collection);
196 }
197 this->collectMap[this->collection]->maintainer = cfgline[line];
198 }
199 }
200 else if (key == "repositoryName" && cfgline.size() >= 1) {
201 int line = 0;
202
203 // TODO: exhaustive checks for empty or default values of repositoryName
204 while (line < cfgline.size()) {
205 if (cfgline[line] != "NULL" &&
206 cfgline[line] != "") {
207 // do something
208 break;
209 }
210 else {
211 line ++;
212 }
213 }
214
215 // Only try to set the configuration if we have a legitimate value ...
216 if (line < cfgline.size()) {
217 // ensure we have a map to write to
218 if (this->collectMap[this->collection] == NULL) {
219 this->collectMap[this->collection] = new oaicollectconfig(this->collection);
220 }
221 this->collectMap[this->collection]->repositoryName = cfgline[line];
222 }
223 }
224}
225
226/**
227 * TODO: store all field values in a map per collection
228 */
229text_t oaiconfig::getCollectionConfig(const text_t &collection, const text_t &field)
230{
231 if (this->collectMap[collection] == NULL) {
232 return "";
233 }
234 if (field == "maintainer") {
235 return this->collectMap[collection]->maintainer;
236 }
237
238 if (field == "repositoryName") {
239 return this->collectMap[collection]->repositoryName;
240 }
241
242 return "";
243}
244
245text_t oaiconfig::getMapping(const text_t &collection, const text_t &collectfield)
246{
247 if (this->collectMap[collection] == NULL) {
248 return "";
249 }
250 return this->collectMap[collection]->fieldMap[collectfield];
251}
252
253/**
254 * Get the mapping for a field in a given collection; if no mapping
255 * exists, the result will be a blank string.
256 */
257text_t oaiconfig::getMapping(const text_t &collection, const text_t &collectfield, const text_t &formatname)
258{
259 text_t fullName = collectfield;
260 fullName.append(":");
261 fullName.append(formatname);
262
263 // try the collection-specific options first
264 if (this->collectMap[collection] != NULL) {
265 // first try the most specific item - this collection, and given that protocol
266 if (this->collectMap[collection]->fieldMap.count(fullName) >= 1) {
267 return this->collectMap[collection]->fieldMap[fullName];
268 }
269 // otherwise, fall back to this collection, and all protocols
270 else if (this->collectMap[collection]->fieldMap.count(collectfield) >= 1) {
271 return this->collectMap[collection]->fieldMap[collectfield];
272 }
273 }
274
275 // if no mappings exist, return an empty item
276 if (this->collectMap[""] == NULL) {
277 return "";
278 }
279
280 // then try generic rules
281 if (this->collectMap[""]->fieldMap.count(fullName) >= 1) {
282 return this->collectMap[""]->fieldMap[fullName];
283 }
284 else {
285 return this->collectMap[""]->fieldMap[collectfield];
286 }
287}
Note: See TracBrowser for help on using the repository browser.