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

Last change on this file since 15401 was 15401, checked in by mdewsnip, 16 years ago

(Untangling colservr/recpt) Deleted setReceptionistServers() from colservr/collectset.cpp, since this required passing in the receptionist, and the colservr should be independent of the receptionist. Changed the one place this function was called (recpt/librarymain.cpp) to do the same functionality.

  • Property svn:keywords set to Author Date Id Revision
File size: 12.7 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
54 if (site_cfg_read (gsdlhome, httpdomain, httpprefix)) {
55 if (!gsdlhome.empty() && directory_exists(gsdlhome)) {
56 collectdir = filename_cat (gsdlhome, "collect");
57 if (read_dir (collectdir, collections)) {
58
59 text_tarray::const_iterator thiscol = collections.begin();
60 text_tarray::const_iterator endcol = collections.end();
61
62 while (thiscol != endcol) {
63 // ignore the modelcol
64 if (*thiscol == "modelcol") {
65 ++thiscol;
66 continue;
67 }
68
69 this->add_collection (*thiscol, gsdlhome);
70
71 ++thiscol;
72 }
73
74 this->add_all_collection_groups(gsdlhome);
75 }
76 }
77 }
78}
79
80collectset::~collectset () {
81 collectservermapclass::iterator here = cservers.begin();
82 collectservermapclass::iterator end = cservers.end();
83
84 while (here != end) {
85 if ((*here).second.c != NULL) {
86 delete (*here).second.c;
87 }
88 ++here;
89 }
90 cservers.clear();
91}
92
93bool collectset::init (ostream &logout) {
94 collectservermapclass::iterator here = cservers.begin();
95 collectservermapclass::iterator end = cservers.end();
96
97 while (here != end) {
98 assert ((*here).second.c != NULL);
99 if ((*here).second.c != NULL) {
100 const colservrconf &configinfo = (*here).second.c->get_configinfo ();
101
102 // configure this collection server
103
104 // note that we read build.cfg before collect.cfg so that the indexmaps
105 // are available to decode defaultindex, defaultsubcollection, and
106 // defaultlanguage
107
108 bool failed_build_cfg = false;
109 if (!build_cfg_read (*((*here).second.c), configinfo.gsdlhome,
110 configinfo.collection)) {
111 failed_build_cfg = true;
112
113 outconvertclass text_t2ascii;
114 logout << text_t2ascii
115 << "Warning: couldn't read build.cfg file for collection \"" //****
116 << configinfo.collection << "\", gsdlhome=\""
117 << configinfo.gsdlhome << "\"\n";
118 }
119
120 bool failed_collect_cfg = false;
121 if (!collect_cfg_read (*((*here).second.c), configinfo.gsdlhome,
122 configinfo.collection)) {
123 failed_collect_cfg = true;
124 outconvertclass text_t2ascii;
125 logout << text_t2ascii
126 << "Warning: couldn't read collect.cfg file for collection \""
127 << configinfo.collection << "\", gsdlhome=\""
128 << configinfo.gsdlhome << "\"\n";
129 }
130
131
132 bool is_colgroup = (*here).second.c->is_collection_group();
133
134 if (failed_collect_cfg) {
135 ++here;
136 continue;
137 }
138
139 if (failed_build_cfg && (!is_colgroup)) {
140 ++here;
141 continue;
142 }
143 // let a failed build.cfg through if its 'collect.cfg' marks it as 'collectgroup true'
144
145 if (!(*here).second.c->init (logout)) return false;
146
147 (*here).second.c->configure("httpdomain",httpdomain);
148 (*here).second.c->configure("httpprefix",httpprefix);
149 }
150 ++here;
151 }
152
153 return true;
154}
155
156collectservermapclass collectset::servers()
157{ return cservers;
158}
159
160
161void collectset::add_all_collections(const text_t &gsdlhome) {
162
163 text_tarray collections;
164 text_t collectdir = filename_cat(gsdlhome, "collect");
165 if (read_dir(collectdir, collections)) {
166
167 text_tarray::const_iterator thiscol = collections.begin();
168 text_tarray::const_iterator endcol = collections.end();
169
170 while (thiscol != endcol) {
171
172 // ignore the modelcol
173 if (*thiscol == "modelcol") {
174 ++thiscol;
175 continue;
176 }
177
178 // create collection server and add to null protocol
179 this->add_collection (*thiscol, gsdlhome);
180
181 ++thiscol;
182 }
183
184 this->add_all_collection_groups(gsdlhome);
185 }
186}
187
188// add_collection sets up the collectionserver and calls
189// add_collectserver
190void collectset::add_collection (const text_t &collection,
191 const text_t &gsdlhome) {
192
193 this->remove_collection(collection);
194
195 // read config file to see if built with mg, mgpp, or lucene
196 // -- we can rely on the collection (and therefore the build.cfg)
197 // being here since this is the null protocol - a nicer way to
198 // do this would be preferable though - Stefan.
199 text_t buildtype = "mg"; // mg is default
200
201 text_tarray cfgline;
202 text_t key;
203 text_t build_cfg = filename_cat(gsdlhome, "collect", collection, "index", "build.cfg");
204 char *build_cfgc = build_cfg.getcstr();
205 ifstream confin(build_cfgc);
206
207 if (confin) {
208 while (read_cfg_line(confin, cfgline) >= 0) {
209 if (cfgline.size() == 2) {
210 key = cfgline[0];
211 cfgline.erase(cfgline.begin());
212 if (key == "buildtype") {
213 buildtype = cfgline[0];
214 break;
215 }
216 }
217 }
218 confin.close();
219 }
220 delete []build_cfgc;
221
222 collectserver *cserver = new collectserver();
223 gdbmclass *gdbmhandler = new gdbmclass();
224
225 // add a null filter
226 filterclass *filter = new filterclass ();
227 cserver->add_filter (filter);
228
229 // add a browse filter
230 browsefilterclass *browsefilter = new browsefilterclass();
231 browsefilter->set_gdbmptr (gdbmhandler);
232
233 cserver->add_filter (browsefilter);
234
235 if (buildtype == "mg") {
236 mgsearch = new mgsearchclass();
237
238 // add a query filter
239 mgqueryfilterclass *queryfilter = new mgqueryfilterclass();
240 queryfilter->set_gdbmptr (gdbmhandler);
241 queryfilter->set_textsearchptr (mgsearch);
242 cserver->add_filter (queryfilter);
243
244 // add a mg and gdbm source
245 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass ();
246 mggdbmsource->set_gdbmptr (gdbmhandler);
247 mggdbmsource->set_textsearchptr (mgsearch);
248 cserver->add_source (mggdbmsource);
249 }
250 else if (buildtype == "mgpp") {
251 mgppsearch = new mgppsearchclass();
252
253 // add a query filter
254 mgppqueryfilterclass *queryfilter = new mgppqueryfilterclass();
255 queryfilter->set_gdbmptr (gdbmhandler);
256 queryfilter->set_textsearchptr (mgppsearch);
257 cserver->add_filter (queryfilter);
258
259 // add a mg and gdbm source
260 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass ();
261 mggdbmsource->set_gdbmptr (gdbmhandler);
262 mggdbmsource->set_textsearchptr (mgppsearch);
263 cserver->add_source (mggdbmsource);
264 }
265 else if (buildtype == "lucene") {
266 lucenesearch = new lucenesearchclass();
267 lucenesearch->set_gsdlhome(gsdlhome);
268
269 // add a query filter
270 lucenequeryfilterclass *queryfilter = new lucenequeryfilterclass();
271 queryfilter->set_gdbmptr (gdbmhandler);
272 queryfilter->set_textsearchptr (lucenesearch);
273 cserver->add_filter (queryfilter);
274
275 // add a lucene and gdbm source
276 lucenegdbmsourceclass *lucenegdbmsource = new lucenegdbmsourceclass ();
277 lucenegdbmsource->set_gdbmptr (gdbmhandler);
278 lucenegdbmsource->set_textsearchptr (lucenesearch);
279 cserver->add_source (lucenegdbmsource);
280 }
281
282 // inform collection server and everything it contains about its
283 // collection name
284 cserver->configure ("collection", collection);
285 cserver->configure ("gsdlhome", gsdlhome);
286
287 cservers.addcollectserver (cserver);
288}
289
290void collectset::remove_all_collections () {
291
292 // first unload any cached mg databases
293 if (mgsearch != NULL) {
294 mgsearch->unload_database();
295 }
296
297 // now delete the collection server objects
298 collectservermapclass::iterator here = cservers.begin();
299 collectservermapclass::iterator end = cservers.end();
300
301 while (here != end) {
302 if ((*here).second.c != NULL) {
303 delete (*here).second.c;
304 }
305 ++here;
306 }
307 cservers.clear();
308}
309
310void collectset::add_collection_group(const text_t& collection,
311 const text_t& gsdlhome)
312{
313 text_tarray group;
314 text_t collect_group_dir = filename_cat (gsdlhome, "collect", collection);
315
316 // need to read collect.cfg for 'collectgroup' as class hasn't been initialised through 'init' yet
317 text_t is_collect_group;
318 text_tarray cfgline;
319 text_t key;
320 text_t build_cfg = filename_cat(gsdlhome, "collect", collection, "etc", "collect.cfg");
321 char *collect_cfgc = build_cfg.getcstr();
322 ifstream confin(collect_cfgc);
323
324 if (confin) {
325 while (read_cfg_line(confin, cfgline) >= 0) {
326 if (cfgline.size() == 2) {
327 key = cfgline[0];
328 cfgline.erase(cfgline.begin());
329 if (key == "collectgroup") {
330 is_collect_group = cfgline[0];
331 break;
332 }
333 }
334 }
335 confin.close();
336 }
337 delete []collect_cfgc;
338
339 if (is_collect_group == "true") {
340
341 if (read_dir (collect_group_dir, group)) {
342
343 text_tarray::const_iterator thiscol = group.begin();
344 text_tarray::const_iterator endcol = group.end();
345
346 while (thiscol != endcol) {
347 // ignore the modelcol
348 if (*thiscol == "etc") {
349 ++thiscol;
350 continue;
351 }
352
353 this->add_collection (collection + "/" + *thiscol, gsdlhome);
354
355 ++thiscol;
356 }
357 }
358 }
359}
360
361void collectset::add_all_collection_groups (const text_t& gsdlhome)
362
363{
364 collectservermapclass::iterator here = cservers.begin();
365 collectservermapclass::iterator end = cservers.end();
366
367 while (here != end) {
368 text_t collection = (*here).second.c->get_collection_name();
369 this->add_collection_group(collection,gsdlhome);
370
371 ++here;
372 }
373}
374
375
376// remove_collection deletes the collection server of collection.
377// This only needs to be called if a collectionserver is to be
378// removed while the library is running. The destructor function
379// cleans up all collectservers when the program exits.
380void collectset::remove_collection (const text_t &collection) {
381
382 // do nothing if no collection server exists for this collection
383 if (cservers.getcollectserver(collection) == NULL) return;
384
385 // first unload any cached mg databases - we may need to do something
386 // similar to this for mgpp and lucene too
387 if (mgsearch != NULL) {
388 mgsearch->unload_database();
389 }
390
391 // now delete the collection server object
392 collectservermapclass::iterator here = cservers.begin();
393 collectservermapclass::iterator end = cservers.end();
394
395 while (here != end) {
396 if ((*here).second.c != NULL && (*here).first == collection) {
397 delete (*here).second.c;
398 cservers.erase (here);
399 return;
400 }
401 ++here;
402 }
403}
404
405
406// remove_collection deletes the collection server of collection.
407// This only needs to be called if a collectionserver is to be
408// removed while the library is running. The destructor function
409// cleans up all collectservers when the program exits.
410void collectset::remove_collection (const text_t &collection, ostream &logout) {
411
412 remove_collection(collection);
413
414 outconvertclass text_t2ascii;
415 logout << text_t2ascii << "nullproto::remove_collection: failed to remove collectserver for "
416 << collection << "\n";
417}
418
419void collectset::configure(const text_t &key, const text_tarray &cfgline)
420{
421 if (key == "collection" || key == "collectdir") return;
422
423 collectservermapclass::iterator here = cservers.begin();
424 collectservermapclass::iterator end = cservers.end();
425
426 while (here != end) {
427 assert ((*here).second.c != NULL);
428 if ((*here).second.c != NULL) {
429 if (key == "collectinfo") {
430 if ((*here).first == cfgline[0]) {
431 (*here).second.c->configure ("gsdlhome", cfgline[1]);
432 (*here).second.c->configure ("gdbmhome", cfgline[2]);
433 }
434 } else {
435 (*here).second.c->configure (key, cfgline);
436 }
437 }
438
439 ++here;
440 }
441}
442
443void collectset::getCollectionList (text_tarray &collist)
444{
445 collist.erase(collist.begin(),collist.end());
446
447 collectservermapclass::iterator here = cservers.begin();
448 collectservermapclass::iterator end = cservers.end();
449 while (here != end) {
450 assert ((*here).second.c != NULL);
451 if ((*here).second.c != NULL) {
452 collist.push_back ((*here).second.c->get_collection_name());
453 }
454 ++here;
455 }
456}
Note: See TracBrowser for help on using the repository browser.