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

Last change on this file since 830 was 830, checked in by davidb, 24 years ago

Support for cross-collection searching (CCS)

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