source: trunk/gsdl/src/colservr/collectset.cpp@ 12246

Last change on this file since 12246 was 12246, checked in by mdewsnip, 18 years ago

GSDLHOME and GSDLOS environment variables need to be set for lucene_query.pl. Thanks to John Thompson and DL Consulting Ltd.

  • Property svn:keywords set to Author Date Id Revision
File size: 14.6 KB
Line 
1/**********************************************************************
2 *
3 * collectset.cpp --
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26
27#include "collectserver.h"
28#include "filter.h"
29#include "browsefilter.h"
30#include "queryfilter.h"
31#include "infodbclass.h"
32#include "mgqueryfilter.h"
33#include "mgppqueryfilter.h"
34#include "mggdbmsource.h"
35#include "lucenequeryfilter.h"
36#include "lucenegdbmsource.h"
37
38#include "fileutil.h"
39#include <assert.h>
40
41#include "colservrconfig.h"
42#include "recptconfig.h"
43#include "fileutil.h"
44#include "collectset.h"
45
46collectset::collectset (text_t &gsdlhome) {
47
48 text_tarray collections;
49 text_t collectdir;
50
51 // get gsdlhome (if we fail the error will be picked up later -- in
52 // cgiwrapper)
53 if (site_cfg_read (gsdlhome, httpdomain, httpprefix)) {
54 if (!gsdlhome.empty() && directory_exists(gsdlhome)) {
55 collectdir = filename_cat (gsdlhome, "collect");
56 if (read_dir (collectdir, collections)) {
57
58 text_tarray::const_iterator thiscol = collections.begin();
59 text_tarray::const_iterator endcol = collections.end();
60
61 while (thiscol != endcol) {
62 // ignore the modelcol
63 if (*thiscol == "modelcol") {
64 ++thiscol;
65 continue;
66 }
67
68 // read config file to see if built with mg, mgpp, or lucene
69 text_t buildtype = "mg"; // mg is default
70 text_tarray cfgline;
71 text_t key;
72 text_t filename = filename_cat(collectdir, *thiscol, "index" , "build.cfg");
73 ifstream confin(filename.getcstr());
74
75 if (confin) {
76 while (read_cfg_line(confin, cfgline) >= 0) {
77 if (cfgline.size() ==2 ) {
78 key = cfgline[0];
79 cfgline.erase(cfgline.begin());
80 if (key =="buildtype") {
81 buildtype = cfgline[0];
82 break;
83 }
84 }
85 }
86 }
87
88 confin.close();
89
90 // this memory is created but never destroyed
91 // we're also not doing any error checking to make sure we didn't
92 // run out of memory
93 collectserver *cserver = new collectserver();
94 gdbmclass *gdbmhandler = new gdbmclass();
95
96 // add a null filter
97 filterclass *filter = new filterclass ();
98 cserver->add_filter (filter);
99
100 // add a browse filter
101 browsefilterclass *browsefilter = new browsefilterclass();
102 browsefilter->set_gdbmptr (gdbmhandler);
103 cserver->add_filter (browsefilter);
104
105 if (buildtype == "mg") {
106 mgsearch = new mgsearchclass();
107
108 // add a query filter
109 mgqueryfilterclass *queryfilter = new mgqueryfilterclass();
110 queryfilter->set_gdbmptr (gdbmhandler);
111 queryfilter->set_textsearchptr (mgsearch);
112 cserver->add_filter (queryfilter);
113
114 // add a mg and gdbm source
115 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass ();
116 mggdbmsource->set_gdbmptr (gdbmhandler);
117 mggdbmsource->set_textsearchptr (mgsearch);
118 cserver->add_source (mggdbmsource);
119
120 }
121 else if (buildtype == "mgpp") {
122
123 mgppsearch = new mgppsearchclass();
124
125 // add a query filter
126 mgppqueryfilterclass *queryfilter = new mgppqueryfilterclass();
127 queryfilter->set_gdbmptr (gdbmhandler);
128 queryfilter->set_textsearchptr (mgppsearch);
129 cserver->add_filter (queryfilter);
130
131 // add a mg and gdbm source
132 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass ();
133 mggdbmsource->set_gdbmptr (gdbmhandler);
134 mggdbmsource->set_textsearchptr (mgppsearch);
135 cserver->add_source (mggdbmsource);
136 }
137 else if (buildtype == "lucene") {
138 lucenesearch = new lucenesearchclass();
139 lucenesearch->set_gsdlhome(gsdlhome);
140
141 // add a query filter
142 lucenequeryfilterclass *queryfilter = new lucenequeryfilterclass();
143 queryfilter->set_gdbmptr (gdbmhandler);
144 queryfilter->set_textsearchptr (lucenesearch);
145 cserver->add_filter (queryfilter);
146
147 // add a lucene and gdbm source
148 lucenegdbmsourceclass *lucenegdbmsource = new lucenegdbmsourceclass ();
149 lucenegdbmsource->set_gdbmptr (gdbmhandler);
150 lucenegdbmsource->set_textsearchptr (lucenesearch);
151 cserver->add_source (lucenegdbmsource);
152 }
153
154
155 // inform collection server and everything it contains about its
156 // collection name
157 cserver->configure ("collection", *thiscol);
158 // AZIZ: added on 10/10/00
159 // the cserver object does not have a reference to gsdlhome
160 cserver->configure ("gsdlhome", gsdlhome);
161
162 // GRB: removed proto.add_collectserver (cserver);
163 // GRB: added to build our own cservers list
164 cservers.addcollectserver (cserver);
165
166 ++thiscol;
167 }
168 }
169 }
170 }
171}
172
173collectset::~collectset () {
174 collectservermapclass::iterator here = cservers.begin();
175 collectservermapclass::iterator end = cservers.end();
176
177 while (here != end) {
178 if ((*here).second.c != NULL) {
179 delete (*here).second.c;
180 }
181 ++here;
182 }
183 cservers.clear();
184}
185
186bool collectset::init (ostream &logout) {
187 collectservermapclass::iterator here = cservers.begin();
188 collectservermapclass::iterator end = cservers.end();
189
190 while (here != end) {
191 assert ((*here).second.c != NULL);
192 if ((*here).second.c != NULL) {
193 const colservrconf &configinfo = (*here).second.c->get_configinfo ();
194
195 // configure this collection server
196
197 // note that we read build.cfg before collect.cfg so that the indexmaps
198 // are available to decode defaultindex, defaultsubcollection, and
199 // defaultlanguage
200 if (!build_cfg_read (*((*here).second.c), configinfo.gsdlhome,
201 configinfo.collection)) {
202 outconvertclass text_t2ascii;
203 logout << text_t2ascii
204 << "Warning: couldn't read build.cfg file for collection \"" //****
205 << configinfo.collection << "\", gsdlhome=\""
206 << configinfo.gsdlhome << "\"\n";
207 ++here;
208 continue;
209 }
210
211 if (!collect_cfg_read (*((*here).second.c), configinfo.gsdlhome,
212 configinfo.collection)) {
213 outconvertclass text_t2ascii;
214 logout << text_t2ascii
215 << "Warning: couldn't read collect.cfg file for collection \""
216 << configinfo.collection << "\", gsdlhome=\""
217 << configinfo.gsdlhome << "\"\n";
218 ++here;
219 continue;
220 }
221
222 if (!(*here).second.c->init (logout)) return false;
223
224 (*here).second.c->configure("httpdomain",httpdomain);
225 (*here).second.c->configure("httpprefix",httpprefix);
226 }
227 ++here;
228 }
229
230 return true;
231}
232
233collectservermapclass collectset::servers()
234{ return cservers;
235}
236
237
238void collectset::add_all_collections(const text_t &gsdlhome) {
239
240 text_tarray collections;
241 text_t collectdir = filename_cat(gsdlhome, "collect");
242 if (read_dir(collectdir, collections)) {
243
244 text_tarray::const_iterator thiscol = collections.begin();
245 text_tarray::const_iterator endcol = collections.end();
246
247 while (thiscol != endcol) {
248
249 // ignore the modelcol
250 if (*thiscol == "modelcol") {
251 ++thiscol;
252 continue;
253 }
254
255 // create collection server and add to null protocol
256 this->add_collection (*thiscol, gsdlhome);
257
258 ++thiscol;
259 }
260 }
261}
262
263// add_collection sets up the collectionserver and calls
264// add_collectserver
265void collectset::add_collection (const text_t &collection,
266 const text_t &gsdlhome) {
267
268 // if an old collection server exists for this collection we should
269 // delete it first
270 collectservermapclass::iterator here = cservers.begin();
271 collectservermapclass::iterator end = cservers.end();
272 while (here != end) {
273 if ((*here).second.c != NULL && (*here).first == collection) {
274 delete (*here).second.c;
275 cservers.erase (here);
276 break;
277 }
278 ++here;
279 }
280
281 // read config file to see if built with mg, mgpp, or lucene
282 // -- we can rely on the collection (and therefore the build.cfg)
283 // being here since this is the null protocol - a nicer way to
284 // do this would be preferable though - Stefan.
285 text_t buildtype = "mg"; // mg is default
286
287 text_tarray cfgline;
288 text_t key;
289 text_t build_cfg = filename_cat(gsdlhome, "collect", collection, "index", "build.cfg");
290 char *build_cfgc = build_cfg.getcstr();
291 ifstream confin(build_cfgc);
292
293 if (confin) {
294 while (read_cfg_line(confin, cfgline) >= 0) {
295 if (cfgline.size() == 2) {
296 key = cfgline[0];
297 cfgline.erase(cfgline.begin());
298 if (key == "buildtype") {
299 buildtype = cfgline[0];
300 break;
301 }
302 }
303 }
304 confin.close();
305 }
306 delete []build_cfgc;
307
308 collectserver *cserver = new collectserver();
309 gdbmclass *gdbmhandler = new gdbmclass();
310
311 // add a null filter
312 filterclass *filter = new filterclass ();
313 cserver->add_filter (filter);
314
315 // add a browse filter
316 browsefilterclass *browsefilter = new browsefilterclass();
317 browsefilter->set_gdbmptr (gdbmhandler);
318
319 cserver->add_filter (browsefilter);
320
321 if (buildtype == "mg") {
322 mgsearch = new mgsearchclass();
323
324 // add a query filter
325 mgqueryfilterclass *queryfilter = new mgqueryfilterclass();
326 queryfilter->set_gdbmptr (gdbmhandler);
327 queryfilter->set_textsearchptr (mgsearch);
328 cserver->add_filter (queryfilter);
329
330 // add a mg and gdbm source
331 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass ();
332 mggdbmsource->set_gdbmptr (gdbmhandler);
333 mggdbmsource->set_textsearchptr (mgsearch);
334 cserver->add_source (mggdbmsource);
335 }
336 else if (buildtype == "mgpp") {
337 mgppsearch = new mgppsearchclass();
338
339 // add a query filter
340 mgppqueryfilterclass *queryfilter = new mgppqueryfilterclass();
341 queryfilter->set_gdbmptr (gdbmhandler);
342 queryfilter->set_textsearchptr (mgppsearch);
343 cserver->add_filter (queryfilter);
344
345 // add a mg and gdbm source
346 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass ();
347 mggdbmsource->set_gdbmptr (gdbmhandler);
348 mggdbmsource->set_textsearchptr (mgppsearch);
349 cserver->add_source (mggdbmsource);
350 }
351 else if (buildtype == "lucene") {
352 lucenesearch = new lucenesearchclass();
353 lucenesearch->set_gsdlhome(gsdlhome);
354
355 // add a query filter
356 lucenequeryfilterclass *queryfilter = new lucenequeryfilterclass();
357 queryfilter->set_gdbmptr (gdbmhandler);
358 queryfilter->set_textsearchptr (lucenesearch);
359 cserver->add_filter (queryfilter);
360
361 // add a lucene and gdbm source
362 lucenegdbmsourceclass *lucenegdbmsource = new lucenegdbmsourceclass ();
363 lucenegdbmsource->set_gdbmptr (gdbmhandler);
364 lucenegdbmsource->set_textsearchptr (lucenesearch);
365 cserver->add_source (lucenegdbmsource);
366 }
367
368 // inform collection server and everything it contains about its
369 // collection name
370 cserver->configure ("collection", collection);
371 cserver->configure ("gsdlhome", gsdlhome);
372
373 /* Removed from add_collection 24/11/2000; already done elsewhere in collectset.
374 // configure receptionist's collectinfo structure
375 text_tarray colinfo;
376 colinfo.push_back (collection);
377 colinfo.push_back (gsdlhome);
378 colinfo.push_back (gdbmhome);
379 */
380 cservers.addcollectserver (cserver);
381}
382
383void collectset::remove_all_collections () {
384
385 // first unload any cached mg databases
386 if (mgsearch != NULL) {
387 mgsearch->unload_database();
388 }
389
390 // now delete the collection server objects
391 collectservermapclass::iterator here = cservers.begin();
392 collectservermapclass::iterator end = cservers.end();
393
394 while (here != end) {
395 if ((*here).second.c != NULL) {
396 delete (*here).second.c;
397 }
398 ++here;
399 }
400 cservers.clear();
401}
402
403
404// remove_collection deletes the collection server of collection.
405// This only needs to be called if a collectionserver is to be
406// removed while the library is running. The destructor function
407// cleans up all collectservers when the program exits.
408void collectset::remove_collection (const text_t &collection, ostream &logout) {
409
410 // do nothing if no collection server exists for this collection
411 if (cservers.getcollectserver(collection) == NULL) return;
412
413 // first unload any cached mg databases - we may need to do something
414 // similar to this for mgpp and lucene too
415 if (mgsearch != NULL) {
416 mgsearch->unload_database();
417 }
418
419 // now delete the collection server object
420 collectservermapclass::iterator here = cservers.begin();
421 collectservermapclass::iterator end = cservers.end();
422
423 while (here != end) {
424 if ((*here).second.c != NULL && (*here).first == collection) {
425 delete (*here).second.c;
426 cservers.erase (here);
427 return;
428 }
429 ++here;
430 }
431 outconvertclass text_t2ascii;
432 logout << text_t2ascii << "nullproto::remove_collection: failed to remove collectserver for "
433 << collection << "\n";
434}
435
436void collectset::configure(const text_t &key, const text_tarray &cfgline)
437{
438 if (key == "collection" || key == "collectdir") return;
439
440 collectservermapclass::iterator here = cservers.begin();
441 collectservermapclass::iterator end = cservers.end();
442
443 while (here != end) {
444 assert ((*here).second.c != NULL);
445 if ((*here).second.c != NULL) {
446 if (key == "collectinfo") {
447 if ((*here).first == cfgline[0]) {
448 (*here).second.c->configure ("gsdlhome", cfgline[1]);
449 (*here).second.c->configure ("gdbmhome", cfgline[2]);
450 }
451 } else {
452 (*here).second.c->configure (key, cfgline);
453 }
454 }
455
456 ++here;
457 }
458}
459
460void collectset::getCollectionList (text_tarray &collist)
461{
462 collist.erase(collist.begin(),collist.end());
463
464 collectservermapclass::iterator here = cservers.begin();
465 collectservermapclass::iterator end = cservers.end();
466 while (here != end) {
467 assert ((*here).second.c != NULL);
468 if ((*here).second.c != NULL) {
469 collist.push_back ((*here).second.c->get_collection_name());
470 }
471 ++here;
472 }
473}
474
475void collectset::setReceptionistServers(receptionist &recpt, text_t &gsdlhome)
476{
477 collectservermapclass::iterator here = cservers.begin();
478 collectservermapclass::iterator end = cservers.end();
479 while (here != end) {
480 assert ((*here).second.c != NULL);
481
482 text_tarray colinfo;
483 colinfo.push_back((*here).second.c->get_collection_name());
484 colinfo.push_back(gsdlhome);
485 colinfo.push_back(gsdlhome);
486 recpt.configure("collectinfo", colinfo);
487
488 ++here;
489 }
490}
Note: See TracBrowser for help on using the repository browser.