root/gsdl/trunk/src/colservr/collectset.cpp @ 15745

Revision 15745, 12.8 KB (checked in by mdewsnip, 11 years ago)

Minor whitespace change.

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