X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fpazpar2_config.c;h=1aef7b40112c406642cca43f138127ca8f507f50;hb=82d7d0c694b86d3e4ca429d47624ea0f8bc19b91;hp=698fb15ab0c31cbc59d3e63f2f8e5d6e5e4f2933;hpb=642c4b23f3b55ba43c0ccd5b0e04edb4758d7921;p=pazpar2-moved-to-github.git diff --git a/src/pazpar2_config.c b/src/pazpar2_config.c index 698fb15..1aef7b4 100644 --- a/src/pazpar2_config.c +++ b/src/pazpar2_config.c @@ -1,5 +1,5 @@ /* This file is part of Pazpar2. - Copyright (C) 2006-2013 Index Data + Copyright (C) Index Data Pazpar2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include +#include #include #include @@ -66,8 +67,19 @@ struct service_xslt static char *xml_context(const xmlNode *ptr, char *res, size_t len) { + xmlAttr *attr = ptr->properties; size_t off = len - 1; + res[off] = '\0'; + for (; attr; attr = attr->next) + { + size_t l = strlen((const char *) attr->name); + if (off <= l + 1) + break; + off = off - l; + memcpy(res + off, attr->name, l); + res[--off] = '@'; + } while (ptr && ptr->type == XML_ELEMENT_NODE) { size_t l = strlen((const char *) ptr->name); @@ -139,8 +151,7 @@ struct conf_service *service_init(struct conf_server *server, service->sortkeys = nmem_malloc(nmem, sizeof(struct conf_sortkey) * service->num_sortkeys); - - + service->xml_node = 0; return service; } @@ -197,7 +208,7 @@ static struct conf_sortkey *conf_service_add_sortkey( struct conf_service *service, int field_id, const char *name, - enum conf_sortkey_type type) + enum conf_metadata_type type) { struct conf_sortkey *sk = 0; NMEM nmem = service->nmem; @@ -271,8 +282,6 @@ void service_destroy(struct conf_service *service) void service_incref(struct conf_service *service) { - yaz_log(YLOG_LOG, "service_incref. p=%p cnt=%d", service, - service->ref_count); pazpar2_incref(&service->ref_count, service->mutex); } @@ -384,6 +393,8 @@ static int parse_metadata(struct conf_service *service, xmlNode *n, type = Metadata_type_year; else if (!strcmp((const char *) xml_type, "date")) type = Metadata_type_date; + else if (!strcmp((const char *) xml_type, "float")) + type = Metadata_type_float; else { yaz_log(YLOG_FATAL, @@ -425,7 +436,7 @@ static int parse_metadata(struct conf_service *service, xmlNode *n, else { yaz_log(YLOG_FATAL, - "Unknown value for medadata/setting: %s", xml_setting); + "Unknown value for metadata/setting: %s", xml_setting); return -1; } } @@ -433,17 +444,29 @@ static int parse_metadata(struct conf_service *service, xmlNode *n, // add a sortkey if so specified if (xml_sortkey && strcmp((const char *) xml_sortkey, "no")) { - enum conf_sortkey_type sk_type; + enum conf_metadata_type sk_type = type; if (merge == Metadata_merge_no) { yaz_log(YLOG_FATAL, "Can't specify sortkey on a non-merged field"); return -1; } + if (!strcmp((const char *) xml_sortkey, "yes")) + ; if (!strcmp((const char *) xml_sortkey, "numeric")) - sk_type = Metadata_sortkey_numeric; + ; else if (!strcmp((const char *) xml_sortkey, "skiparticle")) - sk_type = Metadata_sortkey_skiparticle; + { + if (sk_type == Metadata_type_generic) + sk_type = Metadata_type_skiparticle; + else + { + yaz_log(YLOG_FATAL, + "skiparticle only supported for type=generic: %s", + xml_type); + return -1; + } + } else { yaz_log(YLOG_FATAL, @@ -489,6 +512,18 @@ static int parse_metadata(struct conf_service *service, xmlNode *n, return 0; } + +static void count_metadata(xmlNode *n, int *num_metadata, int *num_sortkeys) +{ + xmlChar *sortkey = xmlGetProp(n, (xmlChar *) "sortkey"); + (*num_metadata)++; + + if (sortkey && strcmp((const char *) sortkey, "no")) + (*num_sortkeys)++; + xmlFree(sortkey); +} + + static struct conf_service *service_create_static(struct conf_server *server, xmlNode *node, const char *service_id) @@ -507,11 +542,18 @@ static struct conf_service *service_create_static(struct conf_server *server, if (n->type == XML_ELEMENT_NODE && !strcmp((const char *) n->name, "metadata")) { - xmlChar *sortkey = xmlGetProp(n, (xmlChar *) "sortkey"); - num_metadata++; - if (sortkey && strcmp((const char *) sortkey, "no")) - num_sortkeys++; - xmlFree(sortkey); + if (n->children) // This is a container, look at its contents. + { + xmlNode *m; + for (m = n->children; m; m = m->next) + { + if (m->type == XML_ELEMENT_NODE && + !strcmp((const char *) m->name, "metadata")) + count_metadata(m, &num_metadata, &num_sortkeys); + } + } + else // This is a metadata-element proper, count it right away. + count_metadata(n, &num_metadata, &num_sortkeys); } service = service_init(server, num_metadata, num_sortkeys, service_id); @@ -608,8 +650,17 @@ static struct conf_service *service_create_static(struct conf_server *server, } else if (!strcmp((const char *) n->name, (const char *) "metadata")) { - if (parse_metadata(service, n, &md_node, &sk_node)) - return 0; + if (n->children) // This is a container, look at its content. + { + xmlNode *m; + for (m = n->children; m; m = m->next) + if ((!strcmp((const char *) m->name, (const char *) "metadata"))) + if (parse_metadata(service, m, &md_node, &sk_node)) + return 0; + } + else // This is a metadata-element proper, count it right away. + if (parse_metadata(service, n, &md_node, &sk_node)) + return 0; } else if (!strcmp((const char *) n->name, (const char *) "xslt")) { @@ -660,7 +711,7 @@ static struct conf_service *service_create_static(struct conf_server *server, if (!strcmp(rank_length, "linear")) service->rank_length = 2; else if (!strcmp(rank_length, "log")) - service->rank_length = 1; + service->rank_length = 1; else if (!strcmp(rank_length, "none")) service->rank_length = 0; else @@ -732,6 +783,14 @@ static struct conf_service *service_create_static(struct conf_server *server, } } } + + { + xmlBufferPtr buf = xmlBufferCreate(); + xmlNodeDump(buf, node->doc, node, 0, 0); + service->xml_node = + nmem_strdupn(service->nmem, (const char *) buf->content, buf->use); + xmlBufferFree(buf); + } return service; } @@ -968,9 +1027,153 @@ struct conf_service *locate_service(struct conf_server *server, return s; } +static void info_service_metadata(struct conf_service *service, WRBUF w) +{ + int i; + struct conf_metadata *md; + + if (service->num_metadata) + { + for (i = 0; i < service->num_metadata; i++) + { + md = &(service->metadata[i]); + wrbuf_puts(w, " name) { + wrbuf_puts(w, " name=\""); + wrbuf_xmlputs(w, md->name); + wrbuf_puts(w, "\""); + } + if (md->brief) { + wrbuf_puts(w, " brief=\"yes\""); + } + if (md->termlist) { + wrbuf_puts(w, " termlist=\"yes\""); + } + if (md->rank) { + wrbuf_puts(w, " rank=\""); + wrbuf_xmlputs(w, md->rank); + wrbuf_puts(w, "\""); + } + if (md->sortkey_offset > 0) { + wrbuf_puts(w, " sortkey=\""); + switch (service->sortkeys[md->sortkey_offset].type) + { + case Metadata_type_relevance: + wrbuf_puts(w, "relevance"); + break; + case Metadata_type_skiparticle: + wrbuf_puts(w, "skiparticle"); + break; + case Metadata_type_position: + wrbuf_puts(w, "position"); + break; + default: + wrbuf_puts(w, "yes"); + break; + } + wrbuf_puts(w, "\""); + } + switch (md->type) + { + case Metadata_type_generic: + case Metadata_type_skiparticle: + break; + case Metadata_type_year: + wrbuf_puts(w, " type=\"year\""); + break; + case Metadata_type_date: + wrbuf_puts(w, " type=\"date\""); + break; + case Metadata_type_float: + wrbuf_puts(w, " type=\"float\""); + break; + case Metadata_type_relevance: + case Metadata_type_position: + break; + } + switch (md->merge) + { + case Metadata_merge_no: + break; + case Metadata_merge_unique: + wrbuf_puts(w, " merge=\"unique\""); + break; + case Metadata_merge_longest: + wrbuf_puts(w, " merge=\"longest\""); + break; + case Metadata_merge_range: + wrbuf_puts(w, " merge=\"range\""); + break; + case Metadata_merge_all: + wrbuf_puts(w, " merge=\"all\""); + break; + case Metadata_merge_first: + wrbuf_puts(w, " merge=\"first\""); + break; + } + switch (md->mergekey) + { + case Metadata_mergekey_no: + break; + case Metadata_mergekey_optional: + wrbuf_puts(w, " mergekey=\"optional\""); + break; + case Metadata_mergekey_required: + wrbuf_puts(w, " mergekey=\"required\""); + break; + } + wrbuf_puts(w, " />\n"); + } + } +} + +static void info_service_databases(struct conf_service *service, WRBUF w) +{ + struct database *db; + struct setting *s; + int i; + + if (service->databases) + { + wrbuf_puts(w, " \n"); + for(db = service->databases; db; db = db->next) + { + wrbuf_puts(w, " id) + { + wrbuf_puts(w, " id=\""); + wrbuf_printf(w, "%s", db->id); + wrbuf_puts(w, "\""); + } + wrbuf_puts(w, ">\n"); + for (i = 0; i < db->num_settings; i++) + { + s = db->settings[i]; + while (s != NULL) + { + wrbuf_puts(w, " name); + wrbuf_puts(w, "\""); + wrbuf_puts(w, " value=\""); + wrbuf_xmlputs(w, s->value); + wrbuf_puts(w, "\""); + wrbuf_puts(w, " />\n"); + s = s->next; + } + } + wrbuf_puts(w, " \n"); + } + wrbuf_puts(w, " \n"); + } +} + void info_services(struct conf_server *server, WRBUF w) { struct conf_service *s = server->service; + int i; + struct setting *S; + wrbuf_puts(w, " \n"); for (; s; s = s->next) { @@ -981,7 +1184,35 @@ void info_services(struct conf_server *server, WRBUF w) wrbuf_xmlputs(w, s->id); wrbuf_puts(w, "\""); } - wrbuf_puts(w, "/>"); + wrbuf_puts(w, ">\n"); + if (s->settings) + { + for (i=0; isettings->num_settings; i++) + { + S = s->settings->settings[i]; + while (S != NULL) { + wrbuf_puts(w, " name); + wrbuf_puts(w, "\""); + wrbuf_puts(w, " value=\""); + wrbuf_xmlputs(w, S->value); + wrbuf_puts(w, "\""); + if (S->target) { + wrbuf_puts(w, " target=\""); + wrbuf_xmlputs(w, S->target); + wrbuf_puts(w, "\""); + } + + wrbuf_puts(w, " />\n"); + + S = S->next; + } + } + } + info_service_metadata(s, w); + info_service_databases(s, w); + wrbuf_puts(w, " "); wrbuf_puts(w, "\n"); } @@ -1030,7 +1261,10 @@ static int parse_config(struct conf_config *config, xmlNode *root) struct conf_config *config_create(const char *fname, int verbose) { - xmlDoc *doc = xmlParseFile(fname); + xmlDoc *doc = xmlReadFile(fname, + NULL, + XML_PARSE_XINCLUDE + + XML_PARSE_NSCLEAN + XML_PARSE_NONET); xmlNode *n; const char *p; int r; @@ -1046,6 +1280,14 @@ struct conf_config *config_create(const char *fname, int verbose) return 0; } + // Perform XInclude. + r = xmlXIncludeProcess(doc); + if (r == -1) + { + yaz_log(YLOG_FATAL, "XInclude processing failed"); + return 0; + } + config->nmem = nmem; config->servers = 0; config->no_threads = 0; @@ -1102,7 +1344,6 @@ void server_destroy(struct conf_server *server) s = s_next; } pp2_charset_fact_destroy(server->charsets); - yaz_log(YLOG_LOG, "server_destroy server=%p", server); http_server_destroy(server->http_server); }