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