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

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

(Adding new DB support) Changed a bunch of "infodbclass.h" to "gdbmclass.h".

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