root/gsdl/trunk/src/protocol/recptprototools.cpp @ 15572

Revision 15572, 7.5 KB (checked in by mdewsnip, 12 years ago)

Moved recptprototools.cpp/h from src/recpt into src/protocol.

  • Property svn:executable set to *
Line 
1/**********************************************************************
2 *
3 * recptprototools.cpp --
4 * Copyright (C) 1999-2008  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#include "recptprototools.h"
27#include <assert.h>
28
29
30// get_info does a protocol call and returns (in response) the metadata
31// associated with OID. Metadata should be loaded with whatever
32// metadata fields are to be requested.
33
34bool get_info (const text_t &OID, const text_t &collection, const text_t &lang,
35           const text_tset &metadata, bool getParents,
36           recptproto *collectproto, FilterResponse_t &response,
37           ostream &logout)
38{
39  response.clear();
40
41  comerror_t err = noError;
42  FilterRequest_t request;
43  request.clear();
44
45  request.filterName = "NullFilter";
46  request.filterLang = lang;
47  request.filterResultOptions = FRmetadata;
48  request.getParents = getParents;
49  request.fields = metadata;
50  request.docSet.push_back (OID);
51  assert (collectproto != NULL);
52
53  collectproto->filter (collection, request, response, err, logout);
54  if (err != noError)
55  {
56    outconvertclass text_t2ascii;
57    logout << text_t2ascii
58       << "Error: call to filter failed for " << OID
59       << " in OIDtools::get_info ("
60       << get_comerror_string (err) << ")\n";
61    return false;
62  }
63 
64  return true;
65}
66
67
68// overloaded, to allow "custom" filter options.
69bool get_info (const text_t &OID, const text_t &collection, const text_t &lang,
70           const text_tset &metadata, const OptionValue_tarray &options,
71           bool getParents,
72           recptproto *collectproto, FilterResponse_t &response,
73           ostream &logout)
74{
75  response.clear();
76
77  comerror_t err = noError;
78  FilterRequest_t request;
79
80  request.filterName = "NullFilter";
81  request.filterLang = lang;
82  request.filterResultOptions = FRmetadata;
83  request.getParents = getParents;
84  request.filterOptions = options;
85  request.fields = metadata;
86  request.docSet.push_back (OID);
87
88  assert (collectproto != NULL);
89  collectproto->filter (collection, request, response, err, logout);
90  if (err != noError)
91  {
92    outconvertclass text_t2ascii;
93    logout << text_t2ascii
94       << "Error: call to filter failed for " << OID
95       << " in OIDtools::get_info ("
96       << get_comerror_string (err) << ")\n";
97    return false;
98  }
99 
100  return true;
101}
102
103
104bool get_info (const text_tarray &OIDs, const text_t &collection, const text_t &lang,
105           const text_tset &metadata, bool getParents,
106           recptproto *collectproto, FilterResponse_t &response,
107           ostream &logout)
108{
109  response.clear();
110  if (OIDs.empty()) return true;
111
112  comerror_t err = noError;
113  FilterRequest_t request;
114
115  request.filterName = "NullFilter";
116  request.filterLang = lang;
117  request.filterResultOptions = FRmetadata;
118  request.getParents = getParents;
119  request.fields = metadata;
120
121  request.docSet = OIDs;
122 
123  collectproto->filter (collection, request, response, err, logout);
124  if (err != noError)
125  {
126    outconvertclass text_t2ascii;
127    logout << text_t2ascii
128       << "Error: call to filter failed in OIDtools::get_info ("
129       << get_comerror_string (err) << ")\n";
130    return false;
131  }
132
133  return true;
134}
135
136
137// has_children returns true if OID has children
138bool has_children (const text_t &OID, const text_t &collection, const text_t &lang,
139           recptproto *collectproto, ostream &logout) {
140
141  FilterResponse_t response;
142  text_tset metadata;
143  metadata.insert ("haschildren");
144
145  if (get_info (OID, collection, lang, metadata, false, collectproto,   response, logout))
146  {
147    if (response.docInfo[0].metadata["haschildren"].values[0] == "1")
148    {
149      return true;
150    }
151  }
152
153  return false;
154}
155
156
157// get_children does a protocol call and returns (in response) the OIDs and
158// metadata of all the children of OID. The metadata set should be loaded
159// with whatever metadata fields are to be requested.
160
161bool get_children (const text_t &OID, const text_t &collection, const text_t &lang,
162           const text_tset &metadata, bool getParents,
163           recptproto *collectproto, FilterResponse_t &response,
164           ostream &logout)
165{
166  response.clear();
167
168  comerror_t err = noError;
169  FilterRequest_t request;
170  OptionValue_t option;
171
172  option.name = "ParentNode";
173  option.value = OID;
174  request.filterOptions.push_back (option);
175  request.filterName = "BrowseFilter";
176  request.filterLang = lang;
177  request.filterResultOptions = FROID;
178
179  // Efficiency improvement: only get the filter to retrieve metadata if some has been requested
180  // Otherwise, the filter makes an unnecessary request to the GDBM database for each child node
181  // By Michael Dewsnip, DL Consulting Ltd
182  if (metadata.size() > 0)
183  {
184    request.filterResultOptions |= FRmetadata;
185  }
186
187  request.fields = metadata;
188  request.getParents = getParents;
189
190  collectproto->filter (collection, request, response, err, logout);
191
192  if (err != noError)
193  {
194    outconvertclass text_t2ascii;
195    logout << text_t2ascii
196       << "Error: call to filter failed for " << OID
197       << " in OIDtools::get_children ("
198       << get_comerror_string (err) << ")\n";
199    return false;
200  }
201
202  return true;
203}
204
205
206static void recurse_contents (ResultDocInfo_t section, const bool &is_classify,
207                  const text_t &collection, const text_t &lang,
208                  const text_tset &metadata,
209                  recptproto *collectproto, FilterResponse_t &response,
210                  ostream &logout)
211{
212  int haschildren = section.metadata["haschildren"].values[0].getint();
213  const text_t &doctype = section.metadata["doctype"].values[0];
214
215  if ((haschildren == 1) && ((!is_classify) || (doctype == "classify")))
216  {
217    FilterResponse_t tmp;
218    bool getParents = false;
219    get_children (section.OID, collection, lang, metadata, getParents, collectproto, tmp, logout);
220    ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin();
221    ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end();
222    while (thisdoc != lastdoc)
223    {
224      response.docInfo.push_back (*thisdoc);
225      recurse_contents (*thisdoc, is_classify, collection, lang, metadata, collectproto, response, logout);
226      ++thisdoc;
227    }
228  }
229}
230
231
232// get_contents returns OIDs and metadata of all contents
233// below (and including) OID.
234void get_contents (const text_t &topOID, const bool &is_classify,
235           text_tset &metadata, const text_t &collection, const text_t &lang,
236           recptproto *collectproto, FilterResponse_t &response,
237           ostream &logout)
238{
239  if (topOID.empty()) return;
240  response.clear();
241
242  metadata.insert ("haschildren");
243  metadata.insert ("doctype");
244
245  // get topOIDs info
246  if (get_info (topOID, collection, lang, metadata, false, collectproto, response, logout))
247  {
248    recurse_contents (response.docInfo[0], is_classify, collection, lang, metadata, collectproto, response, logout);
249  }
250}
Note: See TracBrowser for help on using the browser.