metaproxy  1.21.0
Public Member Functions | Private Attributes | List of all members
metaproxy_1::filter::RecordTransform::Impl Class Reference
Collaboration diagram for metaproxy_1::filter::RecordTransform::Impl:
Collaboration graph

Public Member Functions

 Impl ()
 
 ~Impl ()
 
void process (metaproxy_1::Package &package) const
 
void configure (const xmlNode *xml_node, const char *path)
 

Private Attributes

yaz_retrieval_t m_retrieval
 

Detailed Description

Definition at line 45 of file filter_record_transform.cpp.

Constructor & Destructor Documentation

◆ Impl()

mp::filter::RecordTransform::Impl::Impl ( )

Definition at line 195 of file filter_record_transform.cpp.

196 {
197  m_retrieval = yaz_retrieval_create();
198  assert(m_retrieval);
199 }

◆ ~Impl()

mp::filter::RecordTransform::Impl::~Impl ( )

Definition at line 201 of file filter_record_transform.cpp.

202 {
203  if (m_retrieval)
204  yaz_retrieval_destroy(m_retrieval);
205 }

Member Function Documentation

◆ configure()

void mp::filter::RecordTransform::Impl::configure ( const xmlNode *  xml_node,
const char *  path 
)

Definition at line 207 of file filter_record_transform.cpp.

209 {
210  yaz_retrieval_set_path(m_retrieval, path);
211 
212  if (!xml_node)
213  throw mp::XMLError("RecordTransform filter config: empty XML DOM");
214 
215  // parsing down to retrieval node, which can be any of the children nodes
216  xmlNode *retrieval_node;
217  for (retrieval_node = xml_node->children;
218  retrieval_node;
219  retrieval_node = retrieval_node->next)
220  {
221  if (retrieval_node->type != XML_ELEMENT_NODE)
222  continue;
223  if (0 == strcmp((const char *) retrieval_node->name, "retrievalinfo"))
224  break;
225  }
226 
227 #if HAVE_USEMARCON
228  struct yaz_record_conv_type mt;
229  type_usemarcon(&mt);
230  struct yaz_record_conv_type *t = &mt;
231 #else
232  struct yaz_record_conv_type *t = 0;
233 #endif
234 
235  // read configuration
236  if (0 != yaz_retrieval_configure_t(m_retrieval, retrieval_node, t))
237  {
238  std::string msg("RecordTransform filter config: ");
239  msg += yaz_retrieval_get_error(m_retrieval);
240  throw mp::XMLError(msg);
241  }
242 }

◆ process()

void mp::filter::RecordTransform::Impl::process ( metaproxy_1::Package &  package) const

Definition at line 323 of file filter_record_transform.cpp.

324 {
325 
326  Z_GDU *gdu_req = package.request().get();
327  Z_PresentRequest *pr_req = 0;
328  Z_SearchRequest *sr_req = 0;
329 
330  const char *input_schema = 0;
331  Odr_oid *input_syntax = 0;
332 
333  if (gdu_req && gdu_req->which == Z_GDU_Z3950 &&
334  gdu_req->u.z3950->which == Z_APDU_presentRequest)
335  {
336  pr_req = gdu_req->u.z3950->u.presentRequest;
337 
338  input_schema =
339  mp_util::record_composition_to_esn(pr_req->recordComposition);
340  input_syntax = pr_req->preferredRecordSyntax;
341  }
342  else if (gdu_req && gdu_req->which == Z_GDU_Z3950 &&
343  gdu_req->u.z3950->which == Z_APDU_searchRequest)
344  {
345  sr_req = gdu_req->u.z3950->u.searchRequest;
346 
347  input_syntax = sr_req->preferredRecordSyntax;
348 
349  // we don't know how many hits we're going to get and therefore
350  // the effective element set name.. Therefore we can only allow
351  // two cases.. Both equal or absent.. If not, we'll just have to
352  // disable the piggyback!
353  if (sr_req->smallSetElementSetNames
354  &&
355  sr_req->mediumSetElementSetNames
356  &&
357  sr_req->smallSetElementSetNames->which == Z_ElementSetNames_generic
358  &&
359  sr_req->mediumSetElementSetNames->which == Z_ElementSetNames_generic
360  &&
361  !strcmp(sr_req->smallSetElementSetNames->u.generic,
362  sr_req->mediumSetElementSetNames->u.generic))
363  {
364  input_schema = sr_req->smallSetElementSetNames->u.generic;
365  }
366  else if (*sr_req->largeSetLowerBound > 1
367  && !sr_req->smallSetElementSetNames && !sr_req->mediumSetElementSetNames)
368  ; // input_schema is 0 already
369  else
370  {
371  // disable piggyback (perhaps it was disabled already)
372  *sr_req->smallSetUpperBound = 0;
373  *sr_req->largeSetLowerBound = 1;
374  *sr_req->mediumSetPresentNumber = 0;
375  package.move();
376  return;
377  }
378  // we can handle it in record_transform.
379  }
380  else
381  {
382  package.move();
383  return;
384  }
385 
386  mp::odr odr_en(ODR_ENCODE);
387 
388  // setting up variables for conversion state
389  yaz_record_conv_t rc = 0;
390 
391  const char *match_schema = 0;
392  Odr_oid *match_syntax = 0;
393 
394  const char *backend_schema = 0;
395  Odr_oid *backend_syntax = 0;
396 
397  int ret_code
398  = yaz_retrieval_request(m_retrieval,
399  input_schema, input_syntax,
400  &match_schema, &match_syntax,
401  &rc,
402  &backend_schema, &backend_syntax);
403  // error handling
404  if (ret_code != 0)
405  {
406  int error_code;
407  const char *details = 0;
408 
409  if (ret_code == -1) /* error ? */
410  {
411  details = yaz_retrieval_get_error(m_retrieval);
412  error_code = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
413  }
414  else if (ret_code == 1 || ret_code == 3)
415  {
416  details = input_schema;
417  error_code = YAZ_BIB1_ELEMENT_SET_NAMES_UNSUPP;
418  }
419  else if (ret_code == 2)
420  {
421  char oidbuf[OID_STR_MAX];
422  oid_oid_to_dotstring(input_syntax, oidbuf);
423  details = odr_strdup(odr_en, oidbuf);
424  error_code = YAZ_BIB1_RECORD_SYNTAX_UNSUPP;
425  }
426  else
427  {
428  char *tmp = (char*) odr_malloc(odr_en, 80);
429  sprintf(tmp,
430  "record_transform: yaz_retrieval_get_error returned %d",
431  ret_code);
432  details = tmp;
433  error_code = YAZ_BIB1_UNSPECIFIED_ERROR;
434  }
435  Z_APDU *apdu;
436  if (sr_req)
437  {
438  apdu = odr_en.create_searchResponse(
439  gdu_req->u.z3950, error_code, details);
440  }
441  else
442  {
443  apdu = odr_en.create_presentResponse(
444  gdu_req->u.z3950, error_code, details);
445  }
446  package.response() = apdu;
447  return;
448  }
449 
450  if (sr_req)
451  {
452  if (backend_syntax)
453  sr_req->preferredRecordSyntax = odr_oiddup(odr_en, backend_syntax);
454  else
455  sr_req->preferredRecordSyntax = 0;
456 
457  if (backend_schema)
458  {
459  sr_req->smallSetElementSetNames
460  = (Z_ElementSetNames *)
461  odr_malloc(odr_en, sizeof(Z_ElementSetNames));
462  sr_req->smallSetElementSetNames->which = Z_ElementSetNames_generic;
463  sr_req->smallSetElementSetNames->u.generic
464  = odr_strdup(odr_en, backend_schema);
465  sr_req->mediumSetElementSetNames = sr_req->smallSetElementSetNames;
466  }
467  else
468  {
469  sr_req->smallSetElementSetNames = 0;
470  sr_req->mediumSetElementSetNames = 0;
471  }
472  }
473  else if (pr_req)
474  {
475  if (backend_syntax)
476  pr_req->preferredRecordSyntax = odr_oiddup(odr_en, backend_syntax);
477  else
478  pr_req->preferredRecordSyntax = 0;
479 
480  if (backend_schema)
481  {
482  pr_req->recordComposition
483  = (Z_RecordComposition *)
484  odr_malloc(odr_en, sizeof(Z_RecordComposition));
485  pr_req->recordComposition->which
486  = Z_RecordComp_simple;
487  pr_req->recordComposition->u.simple
488  = (Z_ElementSetNames *)
489  odr_malloc(odr_en, sizeof(Z_ElementSetNames));
490  pr_req->recordComposition->u.simple->which = Z_ElementSetNames_generic;
491  pr_req->recordComposition->u.simple->u.generic
492  = odr_strdup(odr_en, backend_schema);
493  }
494  else
495  pr_req->recordComposition = 0;
496  }
497 
498  // attaching Z3950 package to filter chain
499  package.request() = gdu_req;
500 
501  package.move();
502 
503  Z_GDU *gdu_res = package.response().get();
504 
505  // see if we have a records list to patch!
506  Z_NamePlusRecordList *records = 0;
507  if (gdu_res && gdu_res->which == Z_GDU_Z3950 &&
508  gdu_res->u.z3950->which == Z_APDU_presentResponse)
509  {
510  Z_PresentResponse * pr_res = gdu_res->u.z3950->u.presentResponse;
511 
512  if (rc && pr_res
513  && pr_res->numberOfRecordsReturned
514  && *(pr_res->numberOfRecordsReturned) > 0
515  && pr_res->records
516  && pr_res->records->which == Z_Records_DBOSD)
517  {
518  records = pr_res->records->u.databaseOrSurDiagnostics;
519  }
520  }
521  if (gdu_res && gdu_res->which == Z_GDU_Z3950 &&
522  gdu_res->u.z3950->which == Z_APDU_searchResponse)
523  {
524  Z_SearchResponse *sr_res = gdu_res->u.z3950->u.searchResponse;
525 
526  if (rc && sr_res
527  && sr_res->numberOfRecordsReturned
528  && *(sr_res->numberOfRecordsReturned) > 0
529  && sr_res->records
530  && sr_res->records->which == Z_Records_DBOSD)
531  {
532  records = sr_res->records->u.databaseOrSurDiagnostics;
533  }
534  }
535 
536  if (records)
537  {
538  int i;
539  for (i = 0; i < records->num_records; i++)
540  convert_npr(rc, match_syntax, odr_en, records, i);
541  package.response() = gdu_res;
542  }
543  return;
544 }
static void convert_npr(yaz_record_conv_t rc, Odr_oid *match_syntax, ODR odr_en, Z_NamePlusRecordList *records, int i)

References convert_npr().

Here is the call graph for this function:

Member Data Documentation

◆ m_retrieval

yaz_retrieval_t metaproxy_1::filter::RecordTransform::Impl::m_retrieval
private

Definition at line 52 of file filter_record_transform.cpp.


The documentation for this class was generated from the following file: