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

Last change on this file since 4340 was 4340, checked in by sjboddie, 21 years ago

Tidied up configaction slightly. Running 'a=config&cmd=add-collection'
will now correctly reconfigure the collection if it already exists.

  • Property svn:keywords set to Author Date Id Revision
File size: 12.2 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 * $Id: collectset.cpp 4340 2003-05-26 23:39:16Z sjboddie $
25 *
26 *********************************************************************/
27
28
29#include "collectserver.h"
30#include "filter.h"
31#include "browsefilter.h"
32#include "queryfilter.h"
33#include "infodbclass.h"
34#include "mgqueryfilter.h"
35#include "mgppqueryfilter.h"
36#include "mggdbmsource.h"
37#include "fileutil.h"
38#include <assert.h>
39
40#include "colservrconfig.h"
41#include "recptconfig.h"
42#include "fileutil.h"
43#include "collectset.h"
44
45collectset::collectset (text_t &gsdlhome) {
46
47 text_tarray collections;
48 text_t collectdir;
49
50 // get gsdlhome (if we fail the error will be picked up later -- in
51 // cgiwrapper)
52 if (site_cfg_read (gsdlhome, httpdomain, httpprefix)) {
53 if (directory_exists(gsdlhome)) {
54 collectdir = filename_cat (gsdlhome, "collect");
55 if (read_dir (collectdir, collections)) {
56
57 text_tarray::const_iterator thiscol = collections.begin();
58 text_tarray::const_iterator endcol = collections.end();
59
60 while (thiscol != endcol) {
61 // ignore the modelcol
62 if (*thiscol == "modelcol") {
63 thiscol ++;
64 continue;
65 }
66
67 // read config file to see if built with mg or mgpp
68 text_t buildtype = "mg"; // mg is default
69 text_tarray cfgline;
70 text_t key;
71 text_t filename = filename_cat(collectdir, *thiscol, "index" , "build.cfg");
72 ifstream confin(filename.getcstr());
73
74 if (confin) {
75 while (read_cfg_line(confin, cfgline) >= 0) {
76 if (cfgline.size() ==2 ) {
77 key = cfgline[0];
78 cfgline.erase(cfgline.begin());
79 if (key =="buildtype") {
80 buildtype = cfgline[0];
81 break;
82 }
83 }
84 }
85 }
86
87 confin.close();
88
89 // this memory is created but never destroyed
90 // we're also not doing any error checking to make sure we didn't
91 // run out of memory
92 collectserver *cserver = new collectserver();
93 gdbmclass *gdbmhandler = new gdbmclass();
94
95 // add a null filter
96 filterclass *filter = new filterclass ();
97 cserver->add_filter (filter);
98
99 // add a browse filter
100 browsefilterclass *browsefilter = new browsefilterclass();
101 browsefilter->set_gdbmptr (gdbmhandler);
102 cserver->add_filter (browsefilter);
103
104 if (buildtype == "mg") {
105 mgsearch = new mgsearchclass();
106
107 // add a query filter
108 mgqueryfilterclass *queryfilter = new mgqueryfilterclass();
109 queryfilter->set_gdbmptr (gdbmhandler);
110 queryfilter->set_mgsearchptr (mgsearch);
111 cserver->add_filter (queryfilter);
112
113 // add a mg and gdbm source
114 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass ();
115 mggdbmsource->set_gdbmptr (gdbmhandler);
116 mggdbmsource->set_mgsearchptr (mgsearch);
117 cserver->add_source (mggdbmsource);
118
119 } else if (buildtype == "mgpp") {
120
121 mgppsearch = new mgppsearchclass();
122
123 // add a query filter
124 mgppqueryfilterclass *queryfilter = new mgppqueryfilterclass();
125 queryfilter->set_gdbmptr (gdbmhandler);
126 queryfilter->set_mgsearchptr (mgppsearch);
127 cserver->add_filter (queryfilter);
128
129 // add a mg and gdbm source
130 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass ();
131 mggdbmsource->set_gdbmptr (gdbmhandler);
132 mggdbmsource->set_mgsearchptr (mgppsearch);
133 cserver->add_source (mggdbmsource);
134 }
135
136 // inform collection server and everything it contains about its
137 // collection name
138 cserver->configure ("collection", *thiscol);
139 // AZIZ: added on 10/10/00
140 // the cserver object does not have a reference to gsdlhome
141 cserver->configure ("gsdlhome", gsdlhome);
142
143 // GRB: removed proto.add_collectserver (cserver);
144 // GRB: added to build our own cservers list
145 cservers.addcollectserver (cserver);
146
147 thiscol ++;
148 }
149 }
150 }
151 }
152}
153
154collectset::~collectset () {
155 collectservermapclass::iterator here = cservers.begin();
156 collectservermapclass::iterator end = cservers.end();
157
158 while (here != end) {
159 if ((*here).second.c != NULL) {
160 delete (*here).second.c;
161 }
162 here ++;
163 }
164 cservers.clear();
165}
166
167bool collectset::init (ostream &logout) {
168 collectservermapclass::iterator here = cservers.begin();
169 collectservermapclass::iterator end = cservers.end();
170
171 while (here != end) {
172 assert ((*here).second.c != NULL);
173 if ((*here).second.c != NULL) {
174 const colservrconf &configinfo = (*here).second.c->get_configinfo ();
175
176 // configure this collection server
177
178 // note that we read build.cfg before collect.cfg so that the indexmaps
179 // are available to decode defaultindex, defaultsubcollection, and
180 // defaultlanguage
181 if (!build_cfg_read (*((*here).second.c), configinfo.gsdlhome,
182 configinfo.collection)) {
183 outconvertclass text_t2ascii;
184 logout << text_t2ascii
185 << "Warning: couldn't read build.cfg file for collection \"" //****
186 << configinfo.collection << "\", gsdlhome=\""
187 << configinfo.gsdlhome << "\"\n";
188 here ++;
189 continue;
190 }
191
192 if (!collect_cfg_read (*((*here).second.c), configinfo.gsdlhome,
193 configinfo.collection)) {
194 outconvertclass text_t2ascii;
195 logout << text_t2ascii
196 << "Warning: couldn't read collect.cfg file for collection \""
197 << configinfo.collection << "\", gsdlhome=\""
198 << configinfo.gsdlhome << "\"\n";
199 here ++;
200 continue;
201 }
202
203 if (!(*here).second.c->init (logout)) return false;
204
205 (*here).second.c->configure("httpdomain",httpdomain);
206 (*here).second.c->configure("httpprefix",httpprefix);
207 }
208 here++;
209 }
210
211 return true;
212}
213
214collectservermapclass collectset::servers()
215{ return cservers;
216}
217
218// add_collection sets up the collectionserver and calls
219// add_collectserver
220void collectset::add_collection (const text_t &collection, void *recpt,
221 const text_t &gsdlhome, const text_t &gdbmhome) {
222
223 // if an old collection server exists for this collection we should
224 // delete it first
225 collectservermapclass::iterator here = cservers.begin();
226 collectservermapclass::iterator end = cservers.end();
227 while (here != end) {
228 if ((*here).second.c != NULL && (*here).first == collection) {
229 delete (*here).second.c;
230 cservers.erase (here);
231 break;
232 }
233 here ++;
234 }
235
236 // read config file to see if built with mg or mgpp
237 // -- we can rely on the collection (and therefore the build.cfg)
238 // being here since this is the null protocol - a nicer way to
239 // do this would be preferable though - Stefan.
240 text_t buildtype = "mg"; // mg is default
241
242 text_tarray cfgline;
243 text_t key;
244 text_t build_cfg = filename_cat(gsdlhome, "collect", collection, "index", "build.cfg");
245 char *build_cfgc = build_cfg.getcstr();
246 ifstream confin(build_cfgc);
247
248 if (confin) {
249 while (read_cfg_line(confin, cfgline) >= 0) {
250 if (cfgline.size() == 2) {
251 key = cfgline[0];
252 cfgline.erase(cfgline.begin());
253 if (key == "buildtype") {
254 buildtype = cfgline[0];
255 break;
256 }
257 }
258 }
259 confin.close();
260 }
261 delete build_cfgc;
262
263 collectserver *cserver = new collectserver();
264 gdbmclass *gdbmhandler = new gdbmclass();
265
266 // add a null filter
267 filterclass *filter = new filterclass ();
268 cserver->add_filter (filter);
269
270 // add a browse filter
271 browsefilterclass *browsefilter = new browsefilterclass();
272 browsefilter->set_gdbmptr (gdbmhandler);
273
274 cserver->add_filter (browsefilter);
275
276 if (buildtype == "mg") {
277 mgsearch = new mgsearchclass();
278
279 // add a query filter
280 mgqueryfilterclass *queryfilter = new mgqueryfilterclass();
281 queryfilter->set_gdbmptr (gdbmhandler);
282 queryfilter->set_mgsearchptr (mgsearch);
283 cserver->add_filter (queryfilter);
284
285 // add a mg and gdbm source
286 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass ();
287 mggdbmsource->set_gdbmptr (gdbmhandler);
288 mggdbmsource->set_mgsearchptr (mgsearch);
289 cserver->add_source (mggdbmsource);
290
291 } else if (buildtype == "mgpp") {
292
293 mgppsearch = new mgppsearchclass();
294
295 // add a query filter
296 mgppqueryfilterclass *queryfilter = new mgppqueryfilterclass();
297 queryfilter->set_gdbmptr (gdbmhandler);
298 queryfilter->set_mgsearchptr (mgppsearch);
299 cserver->add_filter (queryfilter);
300
301 // add a mg and gdbm source
302 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass ();
303 mggdbmsource->set_gdbmptr (gdbmhandler);
304 mggdbmsource->set_mgsearchptr (mgppsearch);
305 cserver->add_source (mggdbmsource);
306
307 }
308
309 // inform collection server and everything it contains about its
310 // collection name
311 cserver->configure ("collection", collection);
312
313 /* Removed from add_collection 24/11/2000; already done elsewhere in collectset.
314 // configure receptionist's collectinfo structure
315 text_tarray colinfo;
316 colinfo.push_back (collection);
317 colinfo.push_back (gsdlhome);
318 colinfo.push_back (gdbmhome);
319 */
320 cservers.addcollectserver (cserver);
321}
322
323// remove_collection deletes the collection server of collection.
324// This only needs to be called if a collectionserver is to be
325// removed while the library is running. The destructor function
326// cleans up all collectservers when the program exits.
327void collectset::remove_collection (const text_t &collection, ostream &logout) {
328
329 // do nothing if no collection server exists for this collection
330 if (cservers.getcollectserver(collection) == NULL) return;
331
332 // first unload any cached mg databases - we may need to do something
333 // similar to this for mgpp too
334 if (mgsearch != NULL) {
335 mgsearch->unload_database();
336 }
337
338 // now delete the collection server object
339 collectservermapclass::iterator here = cservers.begin();
340 collectservermapclass::iterator end = cservers.end();
341
342 while (here != end) {
343 if ((*here).second.c != NULL && (*here).first == collection) {
344 delete (*here).second.c;
345 cservers.erase (here);
346 return;
347 }
348 here ++;
349 }
350 outconvertclass text_t2ascii;
351 logout << text_t2ascii << "nullproto::remove_collection: failed to remove collectserver for "
352 << collection << "\n";
353}
354
355void collectset::configure(const text_t &key, const text_tarray &cfgline)
356{
357 if (key == "collection" || key == "collectdir") return;
358
359 collectservermapclass::iterator here = cservers.begin();
360 collectservermapclass::iterator end = cservers.end();
361
362 while (here != end) {
363 assert ((*here).second.c != NULL);
364 if ((*here).second.c != NULL) {
365 if (key == "collectinfo") {
366 if ((*here).first == cfgline[0]) {
367 (*here).second.c->configure ("gsdlhome", cfgline[1]);
368 (*here).second.c->configure ("gdbmhome", cfgline[2]);
369 }
370 } else {
371 (*here).second.c->configure (key, cfgline);
372 }
373 }
374
375 here++;
376 }
377}
378
379void collectset::getCollectionList (text_tarray &collist)
380{
381 collist.erase(collist.begin(),collist.end());
382
383 collectservermapclass::iterator here = cservers.begin();
384 collectservermapclass::iterator end = cservers.end();
385 while (here != end) {
386 assert ((*here).second.c != NULL);
387 if ((*here).second.c != NULL) {
388 collist.push_back ((*here).second.c->get_collection_name());
389 }
390 here++;
391 }
392}
393
394void collectset::setReceptionistServers(receptionist &recpt, text_t &gsdlhome)
395{
396 collectservermapclass::iterator here = cservers.begin();
397 collectservermapclass::iterator end = cservers.end();
398 while (here != end) {
399 assert ((*here).second.c != NULL);
400
401 text_tarray colinfo;
402 colinfo.push_back((*here).second.c->get_collection_name());
403 colinfo.push_back(gsdlhome);
404 colinfo.push_back(gsdlhome);
405 recpt.configure("collectinfo", colinfo);
406
407 here++;
408 }
409}
Note: See TracBrowser for help on using the repository browser.