YAZ  5.23.1
retrieval.c
Go to the documentation of this file.
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
10 #if HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13 
14 #include <string.h>
15 #include <yaz/retrieval.h>
16 #include <yaz/wrbuf.h>
17 #include <yaz/xmalloc.h>
18 #include <yaz/nmem.h>
19 #include <yaz/tpath.h>
20 #include <yaz/match_glob.h>
21 #include <yaz/proto.h>
22 #include <yaz/oid_db.h>
23 
24 #if YAZ_HAVE_XML2
25 #include <libxml/parser.h>
26 #include <libxml/tree.h>
27 #include <libxml/xinclude.h>
28 
33 
36 
39 
41  char *path;
42 
45 
48 };
49 
53  const char *identifier;
55  const char *name;
58 
60  const char *backend_name;
63 
66 
69 };
70 
72 
74 {
75  yaz_retrieval_t p = (yaz_retrieval_t) xmalloc(sizeof(*p));
77  p->nmem = odr_getmem(p->odr);
78  p->wr_error = wrbuf_alloc();
79  p->list = 0;
80  p->path = 0;
82  return p;
83 }
84 
86 {
87  if (p)
88  {
90  odr_destroy(p->odr);
92  xfree(p->path);
93  xfree(p);
94  }
95 }
96 
98 {
99  struct yaz_retrieval_elem *el = p->list;
100  for(; el; el = el->next)
102 
104  odr_reset(p->odr);
105 
106  p->list = 0;
107  p->list_p = &p->list;
108 }
109 
111 static int conf_retrieval(yaz_retrieval_t p, const xmlNode *ptr,
112  struct yaz_record_conv_type *types)
113 {
114  struct _xmlAttr *attr;
115  struct yaz_retrieval_elem *el = (struct yaz_retrieval_elem *)
116  nmem_malloc(p->nmem, sizeof(*el));
117 
118  el->syntax = 0;
119  el->identifier = 0;
120  el->name = 0;
121  el->backend_name = 0;
122  el->backend_syntax = 0;
123 
124  el->next = 0;
125 
126  for (attr = ptr->properties; attr; attr = attr->next)
127  {
128  if (!xmlStrcmp(attr->name, BAD_CAST "syntax") &&
129  attr->children && attr->children->type == XML_TEXT_NODE)
130  {
132  yaz_oid_std(),
133  CLASS_RECSYN,
134  (const char *) attr->children->content,
135  p->odr);
136  if (!el->syntax)
137  {
138  wrbuf_printf(p->wr_error, "Element <retrieval>: "
139  " unknown attribute value syntax='%s'",
140  (const char *) attr->children->content);
141  return -1;
142  }
143  }
144  else if (!xmlStrcmp(attr->name, BAD_CAST "identifier") &&
145  attr->children && attr->children->type == XML_TEXT_NODE)
146  el->identifier =
147  nmem_strdup(p->nmem, (const char *) attr->children->content);
148  else if (!xmlStrcmp(attr->name, BAD_CAST "name") &&
149  attr->children && attr->children->type == XML_TEXT_NODE)
150  el->name =
151  nmem_strdup(p->nmem, (const char *) attr->children->content);
152  else
153  {
154  wrbuf_printf(p->wr_error, "Element <retrieval>: "
155  " expected attributes 'syntax', identifier' or "
156  "'name', got '%s'", attr->name);
157  return -1;
158  }
159  }
160 
161  if (!el->syntax)
162  {
163  wrbuf_printf(p->wr_error, "Missing 'syntax' attribute");
164  return -1;
165  }
166 
167  /* parsing backend element */
168 
169  el->record_conv = 0; /* OK to have no 'backend' sub content */
170  for (ptr = ptr->children; ptr; ptr = ptr->next)
171  {
172  if (ptr->type != XML_ELEMENT_NODE)
173  continue;
174  if (strcmp((const char *) ptr->name, "backend"))
175  {
176  wrbuf_printf(p->wr_error, "Element <retrieval>: expected"
177  " zero or one element <backend>, got <%s>",
178  (const char *) ptr->name);
179  return -1;
180  }
181  else
182  {
183  struct _xmlAttr *attr;
184  if (el->record_conv)
185  {
186  wrbuf_printf(p->wr_error, "Element <retrieval>: "
187  "only one <backend> allowed");
189  return -1;
190  }
191  /* parsing attributees */
192  for (attr = ptr->properties; attr; attr = attr->next)
193  {
194  if (!xmlStrcmp(attr->name, BAD_CAST "name")
195  && attr->children
196  && attr->children->type == XML_TEXT_NODE)
197  el->backend_name
198  = nmem_strdup(p->nmem,
199  (const char *) attr->children->content);
200 
201  else if (!xmlStrcmp(attr->name, BAD_CAST "syntax")
202  && attr->children
203  && attr->children->type == XML_TEXT_NODE)
204  {
205  el->backend_syntax
207  yaz_oid_std(),
208  CLASS_RECSYN,
209  (const char *) attr->children->content,
210  p->odr);
211  if (!el->backend_syntax)
212  {
214  "Element <backend syntax='%s'>: "
215  "attribute 'syntax' has invalid "
216  "value '%s'",
217  attr->children->content,
218  attr->children->content);
219  return -1;
220  }
221  }
222  else
223  {
224  wrbuf_printf(p->wr_error, "Element <backend>: expected "
225  "attributes 'syntax' or 'name, got '%s'",
226  attr->name);
227  return -1;
228  }
229  }
230 
231  /* parsing internal of record conv */
233 
235 
236  if (yaz_record_conv_configure_t(el->record_conv, ptr, types))
237  {
238  wrbuf_printf(p->wr_error, "%s",
241  return -1;
242  }
243  }
244  }
245 
246  *p->list_p = el;
247  p->list_p = &el->next;
248  return 0;
249 }
250 
251 int yaz_retrieval_configure_t(yaz_retrieval_t p, const xmlNode *ptr,
252  struct yaz_record_conv_type *types)
253 {
255 
256  if (ptr && ptr->type == XML_ELEMENT_NODE &&
257  !strcmp((const char *) ptr->name, "retrievalinfo"))
258  {
259  for (ptr = ptr->children; ptr; ptr = ptr->next)
260  {
261  if (ptr->type != XML_ELEMENT_NODE)
262  continue;
263  if (!strcmp((const char *) ptr->name, "retrieval"))
264  {
265  if (conf_retrieval(p, ptr, types))
266  return -1;
267  }
268  else
269  {
270  wrbuf_printf(p->wr_error, "Element <retrievalinfo>: "
271  "expected element <retrieval>, got <%s>",
272  ptr->name);
273  return -1;
274  }
275  }
276  }
277  else
278  {
279  wrbuf_printf(p->wr_error, "Expected element <retrievalinfo>");
280  return -1;
281  }
282  return 0;
283 }
284 
285 int yaz_retrieval_configure(yaz_retrieval_t p, const xmlNode *ptr)
286 {
287  return yaz_retrieval_configure_t(p, ptr, 0);
288 }
289 
291  const char *schema, Odr_oid *syntax,
292  const char **match_schema, Odr_oid **match_syntax,
293  yaz_record_conv_t *rc,
294  const char **backend_schema,
295  Odr_oid **backend_syntax)
296 {
297  struct yaz_retrieval_elem *el = p->list;
298  int syntax_matches = 0;
299  int schema_matches = 0;
300  struct yaz_retrieval_elem *el_best = 0;
301 
303  if (!el)
304  return 0;
305  for(; el; el = el->next)
306  {
307  int schema_ok = 0;
308  int syntax_ok = 0;
309 
310  if (!schema)
311  schema_ok = 1;
312  else
313  {
314  if (el->name && yaz_match_glob(el->name, schema))
315  schema_ok = 2;
316  if (el->identifier && !strcmp(schema, el->identifier))
317  schema_ok = 2;
318  if (!el->name && !el->identifier)
319  schema_ok = 1;
320  }
321 
322  if (syntax && el->syntax && !oid_oidcmp(syntax, el->syntax))
323  syntax_ok = 1;
324  if (!syntax)
325  syntax_ok = 1;
326 
327  if (syntax_ok)
328  syntax_matches++;
329  if (schema_ok)
330  schema_matches++;
331  if (syntax_ok && schema_ok)
332  {
333  if (!el_best || schema_ok == 2)
334  el_best = el;
335  }
336  }
337  if (el_best)
338  {
339  el = el_best;
340  *match_syntax = el->syntax;
341  if (el->identifier)
342  *match_schema = el->identifier;
343  else
344  *match_schema = 0;
345  if (backend_schema)
346  {
347  if (el->backend_name)
348  {
349  if (*el->backend_name)
350  *backend_schema = el->backend_name;
351  }
352  else
353  *backend_schema = schema;
354  }
355  if (backend_syntax)
356  {
357  if (el->backend_syntax)
358  *backend_syntax = el->backend_syntax;
359  else
360  *backend_syntax = el->syntax;
361  }
362  if (rc)
363  *rc = el->record_conv;
364  return 0;
365  }
366  if (!syntax_matches && syntax)
367  {
368  char buf[OID_STR_MAX];
369  wrbuf_printf(p->wr_error, "%s", oid_oid_to_dotstring(syntax, buf));
370  return 2;
371  }
372  if (schema)
373  wrbuf_printf(p->wr_error, "%s", schema);
374  if (!schema_matches)
375  return 1;
376  return 3;
377 }
378 
380 {
381  return wrbuf_cstr(p->wr_error);
382 }
383 
385 {
386  xfree(p->path);
387  p->path = 0;
388  if (path)
389  p->path = xstrdup(path);
390 }
391 
392 #endif
393 
394 /*
395  * Local variables:
396  * c-basic-offset: 4
397  * c-file-style: "Stroustrup"
398  * indent-tabs-mode: nil
399  * End:
400  * vim: shiftwidth=4 tabstop=8 expandtab
401  */
402 
information per &#39;retrieval&#39; construct
Definition: retrieval.c:51
yaz_retrieval_t yaz_retrieval_create()
Definition: retrieval.c:73
int yaz_retrieval_configure_t(yaz_retrieval_t p, const xmlNode *ptr, struct yaz_record_conv_type *types)
Definition: retrieval.c:251
Header for WRBUF (growing buffer)
const char * yaz_retrieval_get_error(yaz_retrieval_t p)
Definition: retrieval.c:379
#define ODR_ENCODE
Definition: odr.h:96
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
Definition: wrbuf.c:281
int oid_oidcmp(const Odr_oid *o1, const Odr_oid *o2)
compares OIDs
Definition: oid_util.c:34
int yaz_record_conv_configure_t(yaz_record_conv_t p, const xmlNode *ptr, struct yaz_record_conv_type *types)
Definition: record_conv.c:1135
int yaz_match_glob(const char *glob, const char *text)
matches a glob expression against text
Definition: match_glob.c:21
const char * identifier
schema identifier
Definition: retrieval.c:53
void yaz_record_conv_destroy(yaz_record_conv_t p)
Definition: record_conv.c:94
const char * yaz_record_conv_get_error(yaz_record_conv_t p)
Definition: record_conv.c:1284
#define xstrdup(s)
utility macro which calls xstrdup_f
Definition: xmalloc.h:55
short Odr_oid
Definition: oid_util.h:42
struct yaz_retrieval_elem ** list_p
last pointer in retrieval list
Definition: retrieval.c:47
void * nmem_malloc(NMEM n, size_t size)
allocates memory block on NMEM handle
Definition: nmem.c:145
string buffer
Definition: wrbuf.h:42
struct yaz_retrieval_elem * next
next element in list
Definition: retrieval.c:68
ODR odr
ODR memory for configuration.
Definition: retrieval.c:32
Header for OID database.
Odr_oid * yaz_string_to_oid_odr(yaz_oid_db_t oid_list, oid_class oclass, const char *name, ODR o)
creates ODR malloc&#39;ed OID from string
Definition: oid_db.c:72
char * oid_oid_to_dotstring(const Odr_oid *oid, char *oidbuf)
converts OID to string (dot notation)
Definition: oid_util.c:59
void wrbuf_rewind(WRBUF b)
empty WRBUF content (length of buffer set to 0)
Definition: wrbuf.c:47
WRBUF wr_error
string buffer for error messages
Definition: retrieval.c:38
yaz_record_conv_t record_conv
record conversion
Definition: retrieval.c:65
const char * backend_name
backend name
Definition: retrieval.c:60
void odr_reset(ODR o)
Definition: odr.c:226
yaz_oid_db_t yaz_oid_std(void)
returns standard OID database
Definition: oid_db.c:33
#define xfree(x)
utility macro which calls xfree_f
Definition: xmalloc.h:53
File Path utilities.
void yaz_retrieval_destroy(yaz_retrieval_t p)
Definition: retrieval.c:85
void wrbuf_printf(WRBUF b, const char *fmt,...)
writes printf result to WRBUF
Definition: wrbuf.c:178
The internal structure for yaz_retrieval_t.
Definition: retrieval.c:30
void wrbuf_destroy(WRBUF b)
destroy WRBUF and its buffer
Definition: wrbuf.c:38
Header for Z39.50 Protocol.
char * nmem_strdup(NMEM mem, const char *src)
allocates string on NMEM handle (similar strdup)
Definition: nmemsdup.c:18
#define OID_STR_MAX
Definition: oid_util.h:40
void odr_destroy(ODR o)
Definition: odr.c:253
static int conf_retrieval(yaz_retrieval_t p, const xmlNode *ptr, struct yaz_record_conv_type *types)
parse retrieval XML config
Definition: retrieval.c:111
Definition: odr.h:124
Glob expression matcher.
struct yaz_retrieval_elem * list
retrieval list
Definition: retrieval.c:44
int yaz_retrieval_configure(yaz_retrieval_t p, const xmlNode *ptr)
Definition: retrieval.c:285
struct yaz_retrieval_struct * yaz_retrieval_t
Definition: retrieval.h:45
#define xmalloc(x)
utility macro which calls malloc_f
Definition: xmalloc.h:49
NMEM nmem
odr&#39;s NMEM memory (odr->mem)
Definition: retrieval.c:35
yaz_record_conv_t yaz_record_conv_create()
Definition: record_conv.c:1297
Header for memory handling functions.
The internal structure for yaz_record_conv_t.
Definition: record_conv.c:44
Header for Nibble Memory functions.
#define odr_getmem(o)
Definition: odr.h:216
const char * name
schema name , short-hand such as "dc"
Definition: retrieval.c:55
ODR odr_createmem(int direction)
Definition: odr.c:200
int yaz_retrieval_request(yaz_retrieval_t p, const char *schema, Odr_oid *syntax, const char **match_schema, Odr_oid **match_syntax, yaz_record_conv_t *rc, const char **backend_schema, Odr_oid **backend_syntax)
Definition: retrieval.c:290
Odr_oid * syntax
record syntax
Definition: retrieval.c:57
Retrieval utility.
Odr_oid * backend_syntax
backend syntax
Definition: retrieval.c:62
void yaz_retrieval_set_path(yaz_retrieval_t p, const char *path)
Definition: retrieval.c:384
static void yaz_retrieval_reset(yaz_retrieval_t p)
Definition: retrieval.c:97
void yaz_record_conv_set_path(yaz_record_conv_t p, const char *path)
Definition: record_conv.c:1289
WRBUF wrbuf_alloc(void)
construct WRBUF
Definition: wrbuf.c:25
char * path
path for opening files
Definition: retrieval.c:41