Happy new year
[pazpar2-moved-to-github.git] / src / pazpar2_config.c
index 49a73d7..92717e2 100644 (file)
@@ -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
@@ -78,7 +78,7 @@ static char *xml_context(const xmlNode *ptr, char *res, size_t len)
         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);
@@ -150,9 +150,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;
 }
 
@@ -209,7 +207,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;
@@ -273,8 +271,6 @@ void service_destroy(struct conf_service *service)
         if (!pazpar2_decref(&service->ref_count, service->mutex))
         {
             service_xslt_destroy(service);
-            if (service->xml_node)
-                xmlFreeNode(service->xml_node);
             pp2_charset_fact_destroy(service->charsets);
             ccl_qual_rm(&service->ccl_bibset);
             yaz_mutex_destroy(&service->mutex);
@@ -285,8 +281,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);
 }
 
@@ -398,6 +392,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,
@@ -439,7 +435,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;
         }
     }
@@ -447,17 +443,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,
@@ -746,7 +754,14 @@ static struct conf_service *service_create_static(struct conf_server *server,
             }
         }
     }
-    service->xml_node = xmlCopyNode(node, 1);
+
+    {
+        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;
 }
 
@@ -983,9 +998,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, "   <metadata");
+            if (md->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, "   <databases>\n");
+        for(db = service->databases; db; db = db->next)
+        {
+            wrbuf_puts(w, "    <database");
+            if (db->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, "     <setting");
+                    wrbuf_puts(w, " name=\"");
+                    wrbuf_xmlputs(w, s->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, "    </database>\n");
+        }
+        wrbuf_puts(w, "   </databases>\n");
+    }
+}
+
 void info_services(struct conf_server *server, WRBUF w)
 {
     struct conf_service *s = server->service;
+    int i;
+    struct setting *S;
+
     wrbuf_puts(w, " <services>\n");
     for (; s; s = s->next)
     {
@@ -996,7 +1155,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; i<s->settings->num_settings; i++)
+            {
+                S = s->settings->settings[i];
+                while (S != NULL) {
+                    wrbuf_puts(w, "   <setting");
+                    wrbuf_puts(w, " name=\"");
+                    wrbuf_xmlputs(w,  S->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, "  </service>");
 
         wrbuf_puts(w, "\n");
     }
@@ -1117,7 +1304,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);
 }