#include <yaz/zgdu.h>
#include <yaz/diagsrw.h>
#include <yaz/diagsru_update.h>
-#include "facet.h"
+#include <yaz/z-facet-1.h>
YAZ_BEGIN_CDECL
otherinfo.c pquery.c sortspec.c charneg.c initopt.c init_diag.c \
zoom-c.c zoom-z3950.c zoom-sru.c zoom-query.c zoom-record-cache.c \
zoom-event.c \
- record_render.c zoom-socket.c zoom-opt.c zoom-p.h sru-p.h \
+ record_render.c zoom-socket.c zoom-opt.c zoom-p.h sru_facet.c sru-p.h \
grs1disp.c zgdu.c soap.c srw.c srwutil.c uri.c solr.c diag_map.c \
opac_to_xml.c xml_to_opac.c \
cclfind.c ccltoken.c cclerrms.c cclqual.c cclptree.c cclp.h \
Z_FacetList *yaz_oi_get_facetlist(Z_OtherInformation **otherInformation)
{
- int categoryValue = 1;
- Z_External *z_external = 0;
- Z_OtherInformationUnit *oi =
- yaz_oi_update(otherInformation, 0, yaz_oid_userinfo_facet_1,
- categoryValue, 0);
- if (!oi)
- return 0;
- z_external = oi->information.externallyDefinedInfo;
-
- if (z_external && z_external->which == Z_External_userFacets)
- return z_external->u.facetList;
+ Z_OtherInformation *oi = *otherInformation;
+ if (oi)
+ {
+ int i;
+ for (i = 0; i < oi->num_elements; i++)
+ {
+ Z_OtherInformationUnit *oiu = oi->list[i];
+ if (oiu->which == Z_OtherInfo_externallyDefinedInfo
+ && oiu->information.externallyDefinedInfo->which ==
+ Z_External_userFacets)
+ {
+ return oiu->information.externallyDefinedInfo->u.facetList;
+ }
+ }
+ }
return 0;
}
#include <libxml/tree.h>
#endif
+#include <yaz/facet.h>
#include <yaz/xmalloc.h>
#include <yaz/comstack.h>
#include "eventl.h"
rr.errstring = 0;
rr.search_info = 0;
rr.search_input = 0;
+
+ if (srw_req->facetList)
+ yaz_oi_set_facetlist(&rr.search_input, assoc->encode,
+ srw_req->facetList);
+
yaz_log_zquery_level(log_requestdetail,rr.query);
(assoc->init->bend_search)(assoc->backend, &rr);
srw_res->resultSetIdleTime =
odr_intdup(assoc->encode, *rr.srw_setnameIdleTime );
}
-
+
+ srw_res->facetList = yaz_oi_get_facetlist(&rr.search_info);
+ yaz_log(YLOG_LOG, "facetList res = %p",srw_res->facetList);
if (start > rr.hits || start < 1)
{
/* if hits<=0 and start=1 we don't return a diagnostic */
char *yaz_negotiate_sru_version(char *input_ver);
+void yaz_sru_facet_request(ODR, Z_FacetList **facetList, const char **limit);
+
#if YAZ_HAVE_XML2
#include <libxml/parser.h>
#include <libxml/tree.h>
-const char *yaz_element_attribute_value_get(xmlNodePtr ptr, const char *node_name, const char *attribute_name);
+
+xmlNodePtr add_xsd_string(xmlNodePtr ptr, const char *elem, const char *val);
+
+void add_xsd_integer(xmlNodePtr ptr, const char *elem, const Odr_int *val);
+
+xmlNodePtr add_xsd_string_n(xmlNodePtr ptr, const char *elem, const char *val,
+ int len);
+
+void yaz_sru_facet_response(ODR o, Z_FacetList **facetList, xmlNodePtr n);
+
+const char *yaz_element_attribute_value_get(xmlNodePtr ptr,
+ const char *node_name, const char *attribute_name);
#endif
/*
--- /dev/null
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) 1995-2013 Index Data
+ * See the file LICENSE for details.
+ */
+/**
+ * \file sru_facet.c
+ * \brief Implements SRU 2.0 facets
+ */
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <yaz/srw.h>
+#include <yaz/wrbuf.h>
+#if YAZ_HAVE_XML2
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <assert.h>
+#endif
+
+#include "sru-p.h"
+#include <yaz/pquery.h>
+#include <yaz/facet.h>
+
+void yaz_sru_facet_request(ODR o, Z_FacetList **facetList, const char **limit)
+{
+ if (o->direction == ODR_ENCODE)
+ {
+ Z_FacetList *fl = *facetList;
+ if (fl)
+ {
+ int i;
+ WRBUF w = wrbuf_alloc();
+ for (i = 0; i < fl->num; i++)
+ {
+ struct yaz_facet_attr av;
+ yaz_facet_attr_init(&av);
+ yaz_facet_attr_get_z_attributes(fl->elements[i]->attributes,
+ &av);
+ if (av.errcode == 0)
+ {
+ wrbuf_printf(w, "%d", av.limit ? av.limit : -1);
+ if (av.useattr)
+ wrbuf_printf(w, ":%s,", av.useattr);
+ /* av.relation not considered yet */
+ }
+ }
+ if (wrbuf_len(w) > 0)
+ {
+ wrbuf_cut_right(w, 1); /* remove , */
+ *limit = odr_strdup(o, wrbuf_cstr(w));
+ }
+ wrbuf_destroy(w);
+ }
+ }
+ else if (o->direction == ODR_DECODE)
+ {
+ const char *cp = *limit;
+ *facetList = 0;
+ if (cp)
+ {
+ int nor = 0;
+ int limit_val = 0;
+ WRBUF w = wrbuf_alloc();
+ while (sscanf(cp, "%d%n", &limit_val, &nor) >= 1 && nor > 0)
+ {
+ cp += nor;
+ if (wrbuf_len(w))
+ wrbuf_puts(w, ",");
+ if (*cp == ':') /* field name follows */
+ {
+ wrbuf_puts(w, "@attr 1=");
+ while (*++cp && *cp != ',')
+ wrbuf_putc(w, *cp);
+ wrbuf_puts(w, " ");
+ }
+ if (limit_val != -1)
+ wrbuf_printf(w, "@attr 3=%d", limit_val);
+ if (*cp != ',')
+ break;
+ cp++;
+ }
+ if (wrbuf_len(w))
+ *facetList = yaz_pqf_parse_facet_list(o, wrbuf_cstr(w));
+ wrbuf_destroy(w);
+ }
+ }
+}
+
+#if YAZ_HAVE_XML2
+void yaz_sru_facet_response(ODR o, Z_FacetList **facetList, xmlNodePtr n)
+{
+ if (o->direction == ODR_ENCODE)
+ {
+ Z_FacetList *fl = *facetList;
+ if (fl)
+ {
+ int i;
+ const char *ns =
+ "http://docs.oasis-open.org/ns/search-ws/facetedResults";
+ xmlNode *p1 = xmlNewChild(n, 0, BAD_CAST "facetedResults", 0);
+ xmlNsPtr ns_fr = xmlNewNs(p1, BAD_CAST ns, BAD_CAST "fr");
+ xmlSetNs(p1, ns_fr);
+ for (i = 0; i < fl->num; i++)
+ {
+ Z_FacetField *ff = fl->elements[i];
+ xmlNode *p2 = xmlNewChild(p1, 0, BAD_CAST "facet", 0);
+ int j;
+ xmlNode *p3;
+ struct yaz_facet_attr av;
+ yaz_facet_attr_init(&av);
+ yaz_facet_attr_get_z_attributes(ff->attributes, &av);
+ add_xsd_string(p2, "index", av.useattr);
+ p3 = xmlNewChild(p2, 0, BAD_CAST "terms", 0);
+ for (j = 0; j < ff->num_terms; j++)
+ {
+ Z_FacetTerm *ft = ff->terms[j];
+ Z_Term *zt = ft->term;
+ xmlNode *p4 = xmlNewChild(p3, 0, BAD_CAST "term", 0);
+ if (zt->which == Z_Term_general)
+ add_xsd_string_n(p4, "actualTerm",
+ (char *) zt->u.general->buf,
+ zt->u.general->len);
+ if (ft->count)
+ add_xsd_integer(p4, "count", ft->count);
+ }
+ }
+ }
+ }
+}
+
+#endif
+
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <assert.h>
-
+#include <yaz/facet.h>
#include "sru-p.h"
static void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len,
return add_xsd_string_ns(ptr, elem, val, 0);
}
-static void add_xsd_integer(xmlNodePtr ptr, const char *elem,
+void add_xsd_integer(xmlNodePtr ptr, const char *elem,
const Odr_int *val)
{
if (val)
Z_SRW_searchRetrieveRequest *req;
char *recordPacking = 0;
char *recordXMLEscaping = 0;
+ const char *facetLimit = 0;
(*p)->which = Z_SRW_searchRetrieve_request;
req = (*p)->u.request = (Z_SRW_searchRetrieveRequest *)
else if (match_xsd_string(ptr, "stylesheet", o,
&req->stylesheet))
;
- else
- match_xsd_string(ptr, "database", o, &req->database);
+ else if (match_xsd_string(ptr, "database", o, &req->database))
+ ;
+ else if (match_xsd_string(ptr, "facetLimit", o,
+ (char**) &facetLimit))
+ ;
}
if (!req->query)
{
{
req->recordPacking = recordPacking;
}
+ yaz_sru_facet_request(o, &req->facetList, &facetLimit);
}
else if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveResponse"))
{
client_data, ns);
else if (match_element(ptr, "facet_analysis"))
yaz_sru_proxy_decode_facets(o, ptr, &res->facetList);
+ else if (match_element(ptr, "facetedResults"))
+ yaz_sru_facet_response(o, &res->facetList, ptr);
}
}
else if (!xmlStrcmp(method->name, BAD_CAST "explainRequest"))
}
add_xsd_string(ptr, "stylesheet", req->stylesheet);
add_xsd_string(ptr, "database", req->database);
+ {
+ const char *limit = 0;
+ yaz_sru_facet_request(o, &req->facetList, &limit);
+ add_xsd_string(ptr, "facetLimit", limit);
+ }
}
else if ((*p)->which == Z_SRW_searchRetrieve_response)
{
if (res->resultCountPrecision)
add_xsd_string(ptr, "resultCountPrecision",
res->resultCountPrecision);
+ yaz_sru_facet_response(o, &res->facetList, ptr);
}
else if ((*p)->which == Z_SRW_explain_request)
{
char *startRecord = 0;
char *maximumTerms = 0;
char *responsePosition = 0;
+ const char *facetLimit = 0;
Z_SRW_extra_arg *extra_args = 0;
#endif
char **uri_name;
maximumTerms = v;
else if (!strcmp(n, "responsePosition"))
responsePosition = v;
+ else if (!strcmp(n, "facetLimit"))
+ facetLimit = v;
else if (!strcmp(n, "extraRequestData"))
; /* ignoring extraRequestData */
else if (n[0] == 'x' && n[1] == '-')
sr->u.request->recordPacking = recordXMLEscaping;
sr->u.request->packing = recordPacking;
sr->u.request->stylesheet = stylesheet;
+ yaz_sru_facet_request(decode , &sr->u.request->facetList,
+ &facetLimit);
yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
&sr->u.request->maximumRecords,
srw_pdu->u.request->stylesheet);
yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL",
srw_pdu->u.request->resultSetTTL);
+ {
+ const char *facetLimit = 0;
+ yaz_sru_facet_request(encode, &srw_pdu->u.request->facetList,
+ &facetLimit);
+ yaz_add_name_value_str(encode, name, value, &i, "facetLimit",
+ (char *) facetLimit);
+ }
break;
case Z_SRW_explain_request:
value[i++] = "explain";
odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
sprintf(path, "%s?%s", hreq->path, uri_args);
- yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
hreq->path = path;
z_HTTP_header_add_content_type(encode, &hreq->headers,
$(OBJDIR)\soap.obj \
$(OBJDIR)\solr.obj \
$(OBJDIR)\solrtransform.obj \
+ $(OBJDIR)\sru_facet.obj \
$(OBJDIR)\srw.obj \
$(OBJDIR)\srwutil.obj \
$(OBJDIR)\zoom-c.obj \