root/main/trunk/greenstone2/runtime-src/src/protocol/recptprototools.cpp @ 31903

Revision 31903, 10.6 KB (checked in by ak19, 3 years ago)

I hope these are all the changes necessary on the runtime side of GS2 to get the OAI server validation working for GS2: instead of working out the earliest datetime stamp of the OAI repository by comparing the builddate in index/build.cfg of each OAI collection and selecting the earliest, the oai-inf.db is now storing the special earliesttimestamp record. The timestamp of this record represents its collection's earliest timestamp. And the earliest of these among all OAI collections is now the earliest datetime of the OAI repository.

  • 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
34// THIS FILE IS A CANDIDATE FOR REFACTORING: merge get_info methods
35
36// overloaded, to allow "custom" filter options.
37bool get_info (const text_t &OID, const text_t &collection, const text_t &lang,
38           const text_tset &metadata, bool getParents,
39           recptproto *collectproto, FilterResponse_t &response,
40           ostream &logout, int filterResultOptions)
41{
42  response.clear();
43
44  comerror_t err = noError;
45  FilterRequest_t request;
46  request.clear();
47
48  request.filterName = "NullFilter";
49  request.filterLang = lang;
50  request.filterResultOptions = filterResultOptions | FRmetadata;
51  request.getParents = getParents;
52  request.fields = metadata;
53  request.docSet.push_back (OID);
54  assert (collectproto != NULL);
55
56  collectproto->filter (collection, request, response, err, logout);
57  if (err != noError)
58  {
59    outconvertclass text_t2ascii;
60    logout << text_t2ascii
61       << "Error: call to filter failed for " << OID
62       << " in recptprototools::get_info ("
63       << get_comerror_string (err) << ")\n";
64    return false;
65  }
66 
67  return true;
68}
69
70bool get_oai_info (const text_t &OID, const text_t &collection, const text_t &lang,
71           const text_tset &metadata, bool getParents,
72           recptproto *collectproto, FilterResponse_t &response,
73           ostream &logout)
74{
75  // set filteroption to FROAI
76  return get_info(OID, collection, lang, metadata, getParents, collectproto, response, logout, FROAI);
77}
78
79bool get_info (const text_t &OID, const text_t &collection, const text_t &lang,
80           const text_tset &metadata, const OptionValue_tarray &options,
81           bool getParents,
82           recptproto *collectproto, FilterResponse_t &response,
83           ostream &logout)
84{
85  response.clear();
86
87  comerror_t err = noError;
88  FilterRequest_t request;
89
90  request.filterName = "NullFilter";
91  request.filterLang = lang;
92  request.filterResultOptions = FRmetadata;
93  request.getParents = getParents;
94  request.filterOptions = options;
95  request.fields = metadata;
96  request.docSet.push_back (OID);
97
98  assert (collectproto != NULL);
99  collectproto->filter (collection, request, response, err, logout);
100  if (err != noError)
101  {
102    outconvertclass text_t2ascii;
103    logout << text_t2ascii
104       << "Error: call to filter failed for " << OID
105       << " in recptprototools::get_info ("
106       << get_comerror_string (err) << ")\n";
107    return false;
108  }
109 
110  return true;
111}
112
113
114bool get_info (const text_tarray &OIDs, const text_t &collection, const text_t &lang,
115           const text_tset &metadata, bool getParents,
116           recptproto *collectproto, FilterResponse_t &response,
117           ostream &logout)
118{
119  response.clear();
120  if (OIDs.empty()) return true;
121
122  comerror_t err = noError;
123  FilterRequest_t request;
124
125  request.filterName = "NullFilter";
126  request.filterLang = lang;
127  request.filterResultOptions = FRmetadata;
128  request.getParents = getParents;
129  request.fields = metadata;
130
131  request.docSet = OIDs;
132 
133  collectproto->filter (collection, request, response, err, logout);
134  if (err != noError)
135  {
136    outconvertclass text_t2ascii;
137    logout << text_t2ascii
138       << "Error: call to filter failed in recptprototools::get_info ("
139       << get_comerror_string (err) << ")\n";
140    return false;
141  }
142
143  return true;
144}
145
146
147// has_children returns true if OID has children
148bool has_children (const text_t &OID, const text_t &collection, const text_t &lang,
149           recptproto *collectproto, ostream &logout) {
150
151  FilterResponse_t response;
152  text_tset metadata;
153  metadata.insert ("haschildren");
154
155  if (get_info (OID, collection, lang, metadata, true, collectproto,    response, logout))
156  {
157    if (response.docInfo[0].metadata["haschildren"].values[0] == "1")
158    {
159      return true;
160    }
161  }
162
163  return false;
164}
165
166
167// get_children does a protocol call and returns (in response) the OIDs and
168// metadata of all the children of OID. The metadata set should be loaded
169// with whatever metadata fields are to be requested.
170
171bool get_children (const text_t &OID, const text_t &collection, const text_t &lang,
172           const text_tset &metadata, bool getParents,
173           recptproto *collectproto, FilterResponse_t &response,
174           ostream &logout, int filterResultOptions)
175{
176  response.clear();
177
178  comerror_t err = noError;
179  FilterRequest_t request;
180  OptionValue_t option;
181
182  option.name = "ParentNode";
183  option.value = OID;
184  request.filterOptions.push_back (option);
185  request.filterName = "BrowseFilter";
186  request.filterLang = lang;
187  request.filterResultOptions = filterResultOptions | FROID;
188
189  // Efficiency improvement: only get the filter to retrieve metadata if some has been requested
190  // Otherwise, the filter makes an unnecessary request to the database for each child node
191  // By Michael Dewsnip, DL Consulting Ltd
192  if (metadata.size() > 0)
193  {
194    request.filterResultOptions |= FRmetadata;
195  }
196
197  request.fields = metadata;
198  request.getParents = getParents;
199
200  collectproto->filter (collection, request, response, err, logout);
201
202  if (err != noError)
203  {
204    outconvertclass text_t2ascii;
205    logout << text_t2ascii
206       << "Error: call to filter failed for " << OID
207       << " in recptprototools::get_children ("
208       << get_comerror_string (err) << ")\n";
209    return false;
210  }
211
212  return true;
213}
214
215
216static void recurse_contents (ResultDocInfo_t section, const bool &is_classify,
217                  const text_t &collection, const text_t &lang,
218                  const text_tset &metadata,
219                  recptproto *collectproto, FilterResponse_t &response,
220                  ostream &logout)
221{
222  int haschildren = section.metadata["haschildren"].values[0].getint();
223  const text_t &doctype = section.metadata["doctype"].values[0];
224
225  if ((haschildren == 1) && ((!is_classify) || (doctype == "classify")))
226  {
227    FilterResponse_t tmp;
228    bool getParents = true;
229    get_children (section.OID, collection, lang, metadata, getParents, collectproto, tmp, logout);
230    ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin();
231    ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end();
232    while (thisdoc != lastdoc)
233    {
234      response.docInfo.push_back (*thisdoc);
235      recurse_contents (*thisdoc, is_classify, collection, lang, metadata, collectproto, response, logout);
236      ++thisdoc;
237    }
238  }
239}
240
241
242// get_contents returns OIDs and metadata of all contents
243// below (and including) OID.
244void get_contents (const text_t &topOID, const bool &is_classify,
245           text_tset &metadata, const text_t &collection, const text_t &lang,
246           recptproto *collectproto, FilterResponse_t &response,
247           ostream &logout)
248{
249  if (topOID.empty()) return;
250  response.clear();
251
252  metadata.insert ("haschildren");
253  metadata.insert ("doctype");
254
255  // get topOIDs info
256  if (get_info (topOID, collection, lang, metadata, true, collectproto, response, logout))
257  {
258    recurse_contents (response.docInfo[0], is_classify, collection, lang, metadata, collectproto, response, logout);
259  }
260}
261
262
263bool get_metadata_values (const text_t metadata_elements, const text_t metadata_value_filter,
264              const text_t metadata_value_grouping_expression, const text_t &collection,
265              recptproto *collectproto, FilterResponse_t &response, ostream &logout)
266{
267  response.clear();
268
269  comerror_t err = noError;
270  FilterRequest_t request;
271  request.clear();
272
273  request.filterName = "SQLBrowseFilter";
274  request.requestParams = "GetMetadataValues";
275
276  OptionValue_t request_option;
277  request_option.name = "MetadataElements";
278  request_option.value = metadata_elements;
279  request.filterOptions.push_back (request_option);
280  request_option.name = "MetadataValueFilter";
281  request_option.value = metadata_value_filter;
282  request.filterOptions.push_back (request_option);
283  request_option.name = "MetadataValueGroupingExpression";
284  request_option.value = metadata_value_grouping_expression;
285  request.filterOptions.push_back (request_option);
286
287  assert (collectproto != NULL);
288  collectproto->filter (collection, request, response, err, logout);
289  if (err != noError)
290  {
291    outconvertclass text_t2ascii;
292    logout << text_t2ascii
293       << "Error: call to filter failed for " << metadata_elements
294       << " in recptprototools::get_metadata_values ("
295       << get_comerror_string (err) << ")\n";
296    return false;
297  }
298 
299  return true;
300}
301
302
303bool get_documents_with_metadata_value (const text_t metadata_elements, const text_t metadata_value,
304                    const text_t sort_by_metadata_element_name, const text_t &collection,
305                    recptproto *collectproto, FilterResponse_t &response, ostream &logout)
306{
307  response.clear();
308
309  comerror_t err = noError;
310  FilterRequest_t request;
311  request.clear();
312
313  request.filterName = "SQLBrowseFilter";
314  request.requestParams = "GetDocumentsWithMetadataValue";
315
316  OptionValue_t request_option;
317  request_option.name = "MetadataElements";
318  request_option.value = metadata_elements;
319  request.filterOptions.push_back (request_option);
320  request_option.name = "MetadataValue";
321  request_option.value = metadata_value;
322  request.filterOptions.push_back (request_option);
323  request_option.name = "SortByMetadataElement";
324  request_option.value = sort_by_metadata_element_name;
325  request.filterOptions.push_back (request_option);
326
327  assert (collectproto != NULL);
328  collectproto->filter (collection, request, response, err, logout);
329  if (err != noError)
330  {
331    outconvertclass text_t2ascii;
332    logout << text_t2ascii
333       << "Error: call to filter failed for " << metadata_elements << " = " << metadata_value
334       << " in recptprototools::get_documents_with_metadata_value ("
335       << get_comerror_string (err) << ")\n";
336    return false;
337  }
338 
339  return true;
340}
Note: See TracBrowser for help on using the browser.