source: trunk/gsdl/src/colservr/collectserver.cpp@ 1253

Last change on this file since 1253 was 1253, checked in by sjboddie, 24 years ago

added new numsections field to collection info and made the statusaction
recognize it

  • Property svn:keywords set to Author Date Id Revision
File size: 12.3 KB
Line 
1
2/**********************************************************************
3 *
4 * collectserver.cpp --
5 * Copyright (C) 1999 The New Zealand Digital Library Project
6 *
7 * A component of the Greenstone digital library software
8 * from the New Zealand Digital Library Project at the
9 * University of Waikato, New Zealand.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * $Id: collectserver.cpp 1253 2000-06-29 00:22:59Z sjboddie $
26 *
27 *********************************************************************/
28
29/*
30 $Log$
31 Revision 1.21 2000/06/29 00:22:58 sjboddie
32 added new numsections field to collection info and made the statusaction
33 recognize it
34
35 Revision 1.20 1999/12/13 02:56:22 davidb
36 Support for cross-collection searching (CCS)
37
38 Revision 1.19 1999/12/05 21:28:10 sjboddie
39 added support for multiple gsdlhomes and gdbmhomes
40
41 Revision 1.18 1999/11/01 22:06:49 sjboddie
42 removed an assert - collections may at times be empty now
43
44 Revision 1.17 1999/10/19 03:23:39 davidb
45 Collection building support through web pages
46 and internal and external link handling for collection documents
47
48 Revision 1.16 1999/10/10 08:20:35 sjboddie
49 - metadata now returns map rather than array
50 - redesigned browsing support (although it's not finished so
51 won't currently work ;-)
52
53 Revision 1.15 1999/09/07 04:57:20 sjboddie
54 added gpl notice
55
56 Revision 1.14 1999/08/31 22:34:55 rjmcnab
57 Changes to get compiling on AIX.
58
59 Revision 1.13 1999/08/25 04:50:00 sjboddie
60 changed FilterRequest_t::docSet into an array
61
62 Revision 1.12 1999/08/20 01:05:41 sjboddie
63 fixed a bug (or created another one)
64
65 Revision 1.11 1999/08/03 03:32:53 sjboddie
66 added ability to set receptionist from configuration files
67
68 Revision 1.10 1999/07/08 03:58:44 sjboddie
69 format stuff
70
71 Revision 1.9 1999/06/16 02:00:34 sjboddie
72 Few changes to get getParent filter option to return metadata of
73 parents as well as current OID
74
75 Revision 1.8 1999/05/10 03:43:47 sjboddie
76 lots of changes to lots of files - getting document action going
77
78 Revision 1.7 1999/04/30 02:00:45 sjboddie
79 lots of stuff to do with getting documentaction working
80
81 Revision 1.6 1999/04/06 22:20:29 rjmcnab
82 Got browsefilter working.
83
84 Revision 1.5 1999/03/31 23:44:44 rjmcnab
85 Altered the protocol so that the metadata is part of the filter.
86
87 Revision 1.4 1999/03/09 20:58:50 rjmcnab
88 Added dummy filter and metadata results.
89
90 Revision 1.3 1999/03/08 05:07:42 rjmcnab
91 Made some alterations to fit with the changes to the comtypes. Added the
92 "filteroptdefault" configuration option to alter default filter options.
93
94 Revision 1.2 1999/03/03 23:28:29 sjboddie
95
96 Provided stub functions for the protocol
97
98 Revision 1.1 1999/02/21 22:32:56 rjmcnab
99
100 Initial revision.
101
102 */
103
104
105#include "collectserver.h"
106#include "infodbclass.h"
107#include "OIDtools.h"
108#include <assert.h>
109
110
111collectserver::collectserver () {
112 configinfo.collection = "null";
113}
114
115collectserver::~collectserver () {
116}
117
118// configure should be called for each line in the
119// configuration files to configure the collection server and everything
120// it contains. The configuration should take place just before initialisation.
121void collectserver::configure (const text_t &key, const text_tarray &cfgline) {
122 if (cfgline.size() >= 1) {
123 const text_t &value = cfgline[0];
124 if (key == "gsdlhome") configinfo.gsdlhome = value;
125 else if (key == "gdbmhome") configinfo.gdbmhome = value;
126 else if (key == "collection") {
127 configinfo.collection = value;
128 collectinfo.shortInfo.name = value;
129 } else if (key == "collectdir") configinfo.collectdir = value;
130 else if (key == "host") collectinfo.shortInfo.host = value;
131 else if (key == "port") collectinfo.shortInfo.port = value.getint();
132 else if (key == "public") {
133 if (value == "true") collectinfo.isPublic = true;
134 else collectinfo.isPublic = false;
135 } else if (key == "beta") {
136 if (value == "true") collectinfo.isBeta = true;
137 else collectinfo.isBeta = false;
138 } else if (key == "ccscols") collectinfo.ccsCols = cfgline;
139 else if (key == "builddate") collectinfo.buildDate = value.getint();
140 else if (key == "languages") collectinfo.languages = cfgline;
141 else if (key == "numdocs") collectinfo.numDocs = value.getint();
142 else if (key == "numsections") collectinfo.numSections = value.getint();
143 else if (key == "numwords") collectinfo.numWords = value.getint();
144 else if (key == "numbytes") collectinfo.numBytes = value.getint();
145 else if (key == "collectionmeta" && cfgline.size() == 2)
146 collectinfo.collectionmeta[cfgline[0]] = cfgline[1];
147 else if (key == "format" && cfgline.size() == 2)
148 collectinfo.format[cfgline[0]] = cfgline[1];
149 else if (key == "building" && cfgline.size() == 2)
150 collectinfo.building[cfgline[0]] = cfgline[1];
151 else if (key == "receptionist") collectinfo.receptionist = value;
152 }
153
154 // configure the filters
155 filtermapclass::iterator filter_here = filters.begin();
156 filtermapclass::iterator filter_end = filters.end();
157 while (filter_here != filter_end) {
158 assert ((*filter_here).second.f != NULL);
159 if ((*filter_here).second.f != NULL)
160 (*filter_here).second.f->configure(key, cfgline);
161
162 filter_here++;
163 }
164
165 // configure the sources
166 sourcelistclass::iterator source_here = sources.begin();
167 sourcelistclass::iterator source_end = sources.end();
168 while (source_here != source_end) {
169 assert ((*source_here).s != NULL);
170 if ((*source_here).s != NULL)
171 (*source_here).s->configure(key, cfgline);
172
173 source_here++;
174 }
175}
176
177void collectserver::configure (const text_t &key, const text_t &value) {
178 text_tarray cfgline;
179 cfgline.push_back (value);
180 configure(key, cfgline);
181}
182
183
184bool collectserver::init (ostream &logout) {
185 // init the filters
186 filtermapclass::iterator filter_here = filters.begin();
187 filtermapclass::iterator filter_end = filters.end();
188 while (filter_here != filter_end) {
189 assert ((*filter_here).second.f != NULL);
190 if (((*filter_here).second.f != NULL) &&
191 !(*filter_here).second.f->init(logout)) return false;
192
193 filter_here++;
194 }
195
196 // init the sources
197 sourcelistclass::iterator source_here = sources.begin();
198 sourcelistclass::iterator source_end = sources.end();
199 while (source_here != source_end) {
200 assert ((*source_here).s != NULL);
201 if (((*source_here).s != NULL) &&
202 !(*source_here).s->init(logout)) return false;
203
204 source_here++;
205 }
206
207 return true;
208}
209
210
211void collectserver::get_collectinfo (ColInfoResponse_t &reponse,
212 comerror_t &err, ostream &/*logout*/) {
213 reponse = collectinfo;
214 err = noError;
215}
216
217void collectserver::get_filterinfo (InfoFiltersResponse_t &response,
218 comerror_t &err, ostream &/*logout*/) {
219 response.clear ();
220
221 // get a list of filter names
222 filtermapclass::iterator filter_here = filters.begin();
223 filtermapclass::iterator filter_end = filters.end();
224 while (filter_here != filter_end) {
225 response.filterNames.insert ((*filter_here).first);
226 filter_here++;
227 }
228
229 err = noError;
230}
231
232void collectserver::get_filteroptions (const InfoFilterOptionsRequest_t &request,
233 InfoFilterOptionsResponse_t &response,
234 comerror_t &err, ostream &logout) {
235 outconvertclass text_t2ascii;
236
237 filterclass *thisfilter = filters.getfilter(request.filterName);
238 if (thisfilter != NULL) {
239 thisfilter->get_filteroptions (response, err, logout);
240 } else {
241 response.clear ();
242 err = protocolError;
243 logout << text_t2ascii << "Protocol Error: filter options requested for non-existent\n"
244 << "filter \"" << request.filterName << "\".\n\n";
245 }
246}
247
248void collectserver::filter (FilterRequest_t &request,
249 FilterResponse_t &response,
250 comerror_t &err, ostream &logout) {
251 outconvertclass text_t2ascii;
252
253 // translate any ".fc", ".pr" etc. stuff in the docSet
254 text_t translatedOID;
255 text_tarray translatedOIDs;
256 text_tarray::iterator doc_here = request.docSet.begin();
257 text_tarray::iterator doc_end = request.docSet.end();
258 while (doc_here != doc_end) {
259 if (needs_translating (*doc_here)) {
260 sourcelistclass::iterator source_here = sources.begin();
261 sourcelistclass::iterator source_end = sources.end();
262 while (source_here != source_end) {
263 assert ((*source_here).s != NULL);
264 if (((*source_here).s != NULL) &&
265 ((*source_here).s->translate_OID (*doc_here, translatedOID, err, logout))) {
266 if (err != noError) return;
267 break;
268 }
269 source_here++;
270 }
271 translatedOIDs.push_back (translatedOID);
272 } else {
273 translatedOIDs.push_back (*doc_here);
274 }
275 doc_here ++;
276 }
277 request.docSet = translatedOIDs;
278
279 response.clear();
280
281 filterclass *thisfilter = filters.getfilter(request.filterName);
282 if (thisfilter != NULL) {
283 // filter the data
284 thisfilter->filter (request, response, err, logout);
285
286 // fill in the metadata for each of the OIDs (if it is requested)
287 if (request.filterResultOptions & FRmetadata) {
288 bool processed = false;
289 ResultDocInfo_tarray::iterator resultdoc_here = response.docInfo.begin();
290 ResultDocInfo_tarray::iterator resultdoc_end = response.docInfo.end();
291 while (resultdoc_here != resultdoc_end) {
292 // try each of the sources in turn
293 sourcelistclass::iterator source_here = sources.begin();
294 sourcelistclass::iterator source_end = sources.end();
295 while (source_here != source_end) {
296 assert ((*source_here).s != NULL);
297 if (((*source_here).s != NULL) &&
298 ((*source_here).s->get_metadata(request.requestParams, request.refParams,
299 request.getParents, request.fields,
300 (*resultdoc_here).OID, (*resultdoc_here).metadata,
301 err, logout))) {
302 if (err != noError) return;
303 processed = true;
304 break;
305 }
306 source_here++;
307 }
308 if (!processed) {
309 err = protocolError;
310 return;
311 }
312 resultdoc_here++;
313 }
314 }
315
316 } else {
317 response.clear ();
318 err = protocolError;
319 logout << text_t2ascii << "Protocol Error: filter options requested for non-existent\n"
320 << "filter \"" << request.filterName << "\".\n\n";
321 }
322
323 err = noError;
324}
325
326void collectserver::get_document (const DocumentRequest_t &request,
327 DocumentResponse_t &response,
328 comerror_t &err, ostream &logout) {
329
330 sourcelistclass::iterator source_here = sources.begin();
331 sourcelistclass::iterator source_end = sources.end();
332 while (source_here != source_end) {
333 assert ((*source_here).s != NULL);
334 if (((*source_here).s != NULL) &&
335 ((*source_here).s->get_document (request.OID, response.doc, err, logout))) {
336 if (err != noError) return;
337 break;
338 }
339 source_here++;
340 }
341}
342
343
344bool operator==(const collectserverptr &x, const collectserverptr &y) {
345 return (x.c == y.c);
346}
347
348bool operator<(const collectserverptr &x, const collectserverptr &y) {
349 return (x.c < y.c);
350}
351
352
353// thecollectserver remains the property of the calling code but
354// should not be deleted until it is removed from this list.
355void collectservermapclass::addcollectserver (collectserver *thecollectserver) {
356 // can't add a null collection server
357 assert (thecollectserver != NULL);
358 if (thecollectserver == NULL) return;
359
360 // can't add an collection server with no collection name
361 assert (!(thecollectserver->get_collection_name()).empty());
362 if ((thecollectserver->get_collection_name()).empty()) return;
363
364 collectserverptr cptr;
365 cptr.c = thecollectserver;
366 collectserverptrs[thecollectserver->get_collection_name()] = cptr;
367}
368
369// getcollectserver will return NULL if the collectserver could not be found
370collectserver *collectservermapclass::getcollectserver (const text_t &collection) {
371 // can't find a collection with no name
372 if (collection.empty()) return NULL;
373
374 iterator here = collectserverptrs.find (collection);
375 if (here == collectserverptrs.end()) return NULL;
376
377 return (*here).second.c;
378}
379
Note: See TracBrowser for help on using the repository browser.