Prefix match_xsd functions with yaz_-prefix
[yaz-moved-to-github.git] / src / sru_facet.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2013 Index Data
3  * See the file LICENSE for details.
4  */
5 /**
6  * \file sru_facet.c
7  * \brief Implements SRU 2.0 facets
8  */
9 #if HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12
13 #include <stdlib.h>
14
15 #include <yaz/srw.h>
16 #include <yaz/wrbuf.h>
17 #if YAZ_HAVE_XML2
18 #include <libxml/parser.h>
19 #include <libxml/tree.h>
20 #include <assert.h>
21 #endif
22
23 #include "sru-p.h"
24 #include <yaz/pquery.h>
25 #include <yaz/facet.h>
26
27 void yaz_sru_facet_request(ODR o, Z_FacetList **facetList, const char **limit)
28 {
29     if (o->direction == ODR_ENCODE)
30     {
31         Z_FacetList *fl = *facetList;
32         if (fl)
33         {
34             int i;
35             WRBUF w = wrbuf_alloc();
36             for (i = 0; i < fl->num; i++)
37             {
38                 struct yaz_facet_attr av;
39                 yaz_facet_attr_init(&av);
40                 yaz_facet_attr_get_z_attributes(fl->elements[i]->attributes,
41                                                 &av);
42                 if (av.errcode == 0)
43                 {
44                     wrbuf_printf(w, "%d", av.limit ? av.limit : -1);
45                     if (av.useattr)
46                         wrbuf_printf(w, ":%s,", av.useattr);
47                     /* av.relation not considered yet */
48                 }
49             }
50             if (wrbuf_len(w) > 0)
51             {
52                 wrbuf_cut_right(w, 1); /* remove , */
53                 *limit = odr_strdup(o, wrbuf_cstr(w));
54             }
55             wrbuf_destroy(w);
56         }
57     }
58     else if (o->direction == ODR_DECODE)
59     {
60         const char *cp = *limit;
61         *facetList = 0;
62         if (cp)
63         {
64             int nor = 0;
65             int limit_val = 0;
66             WRBUF w = wrbuf_alloc();
67             while (sscanf(cp, "%d%n", &limit_val, &nor) >= 1 && nor > 0)
68             {
69                 cp += nor;
70                 if (wrbuf_len(w))
71                     wrbuf_puts(w, ",");
72                 if (*cp == ':') /* field name follows */
73                 {
74                     wrbuf_puts(w, "@attr 1=");
75                     while (*++cp && *cp != ',')
76                         wrbuf_putc(w, *cp);
77                     wrbuf_puts(w, " ");
78                 }
79                 if (limit_val != -1)
80                     wrbuf_printf(w, "@attr 3=%d", limit_val);
81                 if (*cp != ',')
82                     break;
83                 cp++;
84             }
85             if (wrbuf_len(w))
86                 *facetList = yaz_pqf_parse_facet_list(o, wrbuf_cstr(w));
87             wrbuf_destroy(w);
88         }
89     }
90 }
91
92 #if YAZ_HAVE_XML2
93 void yaz_sru_facet_response(ODR o, Z_FacetList **facetList, xmlNodePtr n)
94 {
95     if (o->direction == ODR_ENCODE)
96     {
97         Z_FacetList *fl = *facetList;
98         if (fl)
99         {
100             int i;
101             const char *ns =
102                 "http://docs.oasis-open.org/ns/search-ws/facetedResults";
103             xmlNode *p1 = xmlNewChild(n, 0, BAD_CAST "facetedResults", 0);
104             xmlNsPtr ns_fr = xmlNewNs(p1, BAD_CAST ns, BAD_CAST "fr");
105             xmlSetNs(p1, ns_fr);
106             for (i = 0; i < fl->num; i++)
107             {
108                 Z_FacetField *ff = fl->elements[i];
109                 xmlNode *p2 = xmlNewChild(p1, 0, BAD_CAST "facet", 0);
110                 int j;
111                 xmlNode *p3;
112                 struct yaz_facet_attr av;
113                 yaz_facet_attr_init(&av);
114                 yaz_facet_attr_get_z_attributes(ff->attributes, &av);
115                 add_xsd_string(p2, "index", av.useattr);
116                 p3 = xmlNewChild(p2, 0, BAD_CAST "terms", 0);
117                 for (j = 0; j < ff->num_terms; j++)
118                 {
119                     Z_FacetTerm *ft = ff->terms[j];
120                     Z_Term *zt = ft->term;
121                     xmlNode *p4 = xmlNewChild(p3, 0, BAD_CAST "term", 0);
122                     if (zt->which == Z_Term_general)
123                         add_xsd_string_n(p4, "actualTerm",
124                                          (char *) zt->u.general->buf,
125                                          zt->u.general->len);
126                     if (ft->count)
127                         add_xsd_integer(p4, "count", ft->count);
128                 }
129             }
130         }
131     }
132     else if (o->direction == ODR_DECODE)
133     {
134         Z_FacetList *fl = (Z_FacetList *) odr_malloc(o, sizeof(*fl));
135         xmlNode *p1;
136
137         fl->num = 0;
138         for (p1 = n->children; p1; p1 = p1->next)
139             if (yaz_match_xsd_element(p1, "facet"))
140                 fl->num++;
141         if (fl->num > 0)
142         {
143             int i = 0;
144             *facetList = fl;
145             fl->elements = (Z_FacetField **)
146                 odr_malloc(o, sizeof(*fl->elements) * fl->num);
147             for (p1 = n->children; p1; p1 = p1->next)
148                 if (yaz_match_xsd_element(p1, "facet"))
149                 {
150                     char *index_name = 0;
151                     xmlNode *p_terms = 0;
152                     xmlNode *p2 = p1->children;
153                     Z_FacetField *ff = (Z_FacetField *)
154                         odr_malloc(o, sizeof(*ff));
155                     fl->elements[i++] = ff;
156                     ff->attributes = 0;
157                     ff->num_terms = 0;
158                     ff->terms = 0;
159                     for (; p2; p2 = p2->next)
160                     {
161                         if (yaz_match_xsd_string(p2, "index", o, &index_name))
162                             ;
163                         else if (yaz_match_xsd_element(p2, "terms"))
164                             p_terms = p2;
165                     }
166                     if (index_name)
167                     {
168                         Z_AttributeList *al =
169                             (Z_AttributeList*) odr_malloc(o, sizeof(*al));
170                         Z_ComplexAttribute *ca =
171                             (Z_ComplexAttribute *) odr_malloc(o, sizeof(*ca));
172                         Z_AttributeElement *ae =
173                             (Z_AttributeElement *) odr_malloc(o, sizeof(*ae));
174                         al->num_attributes = 1;
175                         al->attributes = (Z_AttributeElement **)
176                             odr_malloc(o, sizeof(*al->attributes));
177                         al->attributes[0] = ae;
178                         ae->attributeSet = 0;
179                         ae->attributeType = odr_intdup(o, 1);
180                         ae->which = Z_AttributeValue_complex;
181                         ae->value.complex = ca;
182                         ca->num_semanticAction = 0;
183                         ca->semanticAction = 0;
184                         ca->num_list = 1;
185                         ca->list = (Z_StringOrNumeric **)
186                             odr_malloc(o, sizeof(*ca->list));
187                         ca->list[0] = (Z_StringOrNumeric *)
188                             odr_malloc(o, sizeof(**ca->list));
189                         ca->list[0]->which = Z_StringOrNumeric_string;
190                         ca->list[0]->u.string = index_name;
191                         ff->attributes = al;
192                     }
193                     if (p_terms)
194                     {
195                         xmlNode *p;
196                         int i = 0;
197                         for (p = p_terms->children; p; p = p->next)
198                         {
199                             if (yaz_match_xsd_element(p, "term"))
200                                 ff->num_terms++;
201                         }
202                         if (ff->num_terms)
203                             ff->terms = (Z_FacetTerm **)
204                                 odr_malloc(o,
205                                            sizeof(*ff->terms) * ff->num_terms);
206                         for (p = p_terms->children; p; p = p->next)
207                         {
208                             if (yaz_match_xsd_element(p, "term"))
209                             {
210                                 char *cstr = 0;
211                                 Odr_int *count = 0;
212                                 xmlNode *p2 = p->children;
213                                 for (; p2; p2 = p2->next)
214                                 {
215                                     if (yaz_match_xsd_string(p2, "actualTerm", o,
216                                                          &cstr))
217                                         ;
218                                     else if (yaz_match_xsd_integer(p2, "count", o,
219                                                                &count))
220                                         ;
221                                 }
222                                 if (cstr && count)
223                                 {
224                                     ff->terms[i++] =
225                                         facet_term_create_cstr(o, cstr, *count);
226                                 }
227                             }
228                         }
229                         ff->num_terms = i;
230                         if (ff->num_terms == 0)
231                             ff->terms = 0;
232                     }
233                 }
234
235         }
236     }
237 }
238
239 #endif
240
241
242 /*
243  * Local variables:
244  * c-basic-offset: 4
245  * c-file-style: "Stroustrup"
246  * indent-tabs-mode: nil
247  * End:
248  * vim: shiftwidth=4 tabstop=8 expandtab
249  */
250