Deliver recordSchema in response
authorAdam Dickmeiss <adam@indexdata.dk>
Wed, 7 Jan 2004 11:10:54 +0000 (11:10 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Wed, 7 Jan 2004 11:10:54 +0000 (11:10 +0000)
TODO
etc/config.xml
etc/voyager.xml
include/yaz++/proxy.h
src/yaz-proxy-config.cpp
src/yaz-proxy.cpp

diff --git a/TODO b/TODO
index 4ead807..84b1009 100644 (file)
--- a/TODO
+++ b/TODO
@@ -11,9 +11,11 @@ Deal with Z39.50 options properly.
 
 Deal with Z39.50 messages sizes properly.
 
-For SRW/SRU, set schema for each returned record.
-
 Character set conversion for SRW queries.
 
 Throw proper CQL conversion error.
 
+Honor XPath.
+
+Deal with scan, sort (throw diagnostic).
+
index c03b41f..46adc99 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<!-- $Id: config.xml,v 1.5 2004-01-05 09:31:09 adam Exp $ -->
+<!-- $Id: config.xml,v 1.6 2004-01-07 11:10:54 adam Exp $ -->
 <proxy>
   <target name="bagel">
     <url>indexdata.dk</url>
     <attribute type="1" value="*" error="114"/>
     <syntax type="usmarc"/>
     <syntax type="grs1"/>
-    <syntax type="xml" marcxml="1" stylesheet="MARC21slim2DC.xsl">
-      dc
-      http://www.loc.gov/zing/srw/dcschema/v1.0/
+    <syntax type="xml" marcxml="1" stylesheet="MARC21slim2DC.xsl"
+      identifier="http://www.loc.gov/zing/srw/dcschema/v1.0/"
+       >
+      <name>dc</name>
     </syntax>
-    <syntax type="xml" marcxml="1">
-      marcxml
-      http://www.loc.gov/marcxml/
+    <syntax type="xml" marcxml="1"
+      identifier="http://www.loc.gov/marcxml/"
+      >
+      <name>marcxml</name>
     </syntax>
-    <syntax type="xml" marcxml="1" stylesheet="MARC21slim2MODS.xsl">
-      mods
-      http://www.loc.gov/mods/v3
+    <syntax type="xml" marcxml="1" stylesheet="MARC21slim2MODS.xsl"
+      identifier="http://www.loc.gov/mods/v3"
+      >
+      <name>mods</name>
     </syntax>
     <syntax type="none"/>
     <syntax type="*" error="238"/>
index 5d18575..915f880 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<!-- $Id: voyager.xml,v 1.4 2004-01-05 11:30:17 adam Exp $ -->
+<!-- $Id: voyager.xml,v 1.5 2004-01-07 11:10:55 adam Exp $ -->
 <proxy>
   <!-- define default target and name it voyager -->
   <target default="1" name="voyager">
     <syntax type="opac"/>
     <syntax type="usmarc"/>
     <syntax type="none"/>
-
-    <syntax type="xml" marcxml="1" stylesheet="MARC21slim2DC.xsl">
-      dc
-      http://www.loc.gov/zing/srw/dcschema/v1.0/
+    
+    <syntax type="xml" marcxml="1"
+      identifier="http://www.loc.gov/marcxml/"
+      >
+      <title>MARCXML</title>
+      <name>marcxml</name>
     </syntax>
-    <syntax type="xml" marcxml="1">
-      marcxml
-      http://www.loc.gov/marcxml/
+    <syntax type="xml" marcxml="1" stylesheet="MARC21slim2DC.xsl"
+      identifier="http://www.loc.gov/zing/srw/dcschema/v1.0/"
+      >
+      <title>Dublin Core</title>
+      <name>dc</name>
     </syntax>
-    <syntax type="xml" marcxml="1" stylesheet="MARC21slim2MODS.xsl">
-      mods
-      http://www.loc.gov/mods/v3
+    <syntax type="xml" marcxml="1" stylesheet="MARC21slim2MODS.xsl"
+      identifier="http://www.loc.gov/mods/v3"
+      >
+      <title>MODS</title>
+      <name>mods</name>
     </syntax>
 
     <syntax type="*" error="238"/>
index ebc2be8..0249ef7 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1998-2004, Index Data.
  * See the file LICENSE for details.
  * 
- * $Id: proxy.h,v 1.27 2004-01-06 21:17:42 adam Exp $
+ * $Id: proxy.h,v 1.28 2004-01-07 11:10:55 adam Exp $
  */
 
 #include <sys/time.h>
@@ -59,14 +59,15 @@ public:
     int check_query(ODR odr, const char *name, Z_Query *query, char **addinfo);
     int check_syntax(ODR odr, const char *name,
                     Odr_oid *syntax, Z_RecordComposition *comp,
-                    char **addinfo, char **stylesheet);
+                    char **addinfo, char **stylesheet, char **schema);
     char *get_explain(ODR odr, const char *name, const char *db,
                      int *len);
 private:
     void operator=(const Yaz_ProxyConfig &conf);
     int mycmp(const char *hay, const char *item, size_t len);
 #if HAVE_XSLT
-    int check_esn(xmlNodePtr ptr, Z_RecordComposition *comp);
+    int check_schema(xmlNodePtr ptr, Z_RecordComposition *comp,
+                    const char **found_schema, const char *schema_identifier);
     xmlDocPtr m_docPtr;
     xmlNodePtr m_proxyPtr;
     void return_target_info(xmlNodePtr ptr, const char **url,
@@ -238,6 +239,7 @@ class YAZ_EXPORT Yaz_Proxy : public Yaz_Z_Assoc {
     int m_invalid_session;
     int m_marcxml_flag;
     char *m_stylesheet;
+    char *m_schema;
     void convert_to_marcxml(Z_NamePlusRecordList *p);
     void convert_xsl(Z_NamePlusRecordList *p);
     Z_APDU *m_initRequest_apdu;
index 3c0e2ff..0e5fe31 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 1998-2003, Index Data.
+ * Copyright (c) 1998-2004, Index Data.
  * See the file LICENSE for details.
  * 
- * $Id: yaz-proxy-config.cpp,v 1.19 2004-01-06 21:17:42 adam Exp $
+ * $Id: yaz-proxy-config.cpp,v 1.20 2004-01-07 11:10:55 adam Exp $
  */
 
 #include <ctype.h>
@@ -345,40 +345,45 @@ int Yaz_ProxyConfig::check_query(ODR odr, const char *name, Z_Query *query,
 }
 
 #if HAVE_XSLT
-int Yaz_ProxyConfig::check_esn(xmlNodePtr ptr, Z_RecordComposition *comp)
+int Yaz_ProxyConfig::check_schema(xmlNodePtr ptr, Z_RecordComposition *comp,
+                                 const char **found_schema,
+                                 const char *schema_identifier)
 {
     char *esn = 0;
     int default_match = 1;
+    *found_schema = schema_identifier;  // may be NULL
     if (comp && comp->which == Z_RecordComp_simple &&
        comp->u.simple && comp->u.simple->which == Z_ElementSetNames_generic)
     {
        esn = comp->u.simple->u.generic;
     }
+    // if no ESN/schema was given accept..
     if (!esn)
        return 1;
+    // check if schema identifier match
+    if (schema_identifier && !strcmp(esn, schema_identifier))
+       return 1;
+    *found_schema = esn;
+    // Check each name element
     for (; ptr; ptr = ptr->next)
     {
-       if (ptr->type == XML_TEXT_NODE)
+       if (ptr->type == XML_ELEMENT_NODE 
+           && !strcmp((const char *) ptr->name, "name"))
        {
+           xmlNodePtr tptr = ptr->children;
            default_match = 0;
-           xmlChar *t = ptr->content;
-           while (*t)
-           {
-               while (*t && isspace(*t))
-                   t++;
-               xmlChar *s = t;
-               int i = 0;
-               while (esn[i] && esn[i] == *s)
+           for (; tptr; tptr = tptr->next)
+               if (tptr->type == XML_TEXT_NODE && tptr->content)
                {
-                   i++;
-                   s++;
+                   xmlChar *t = tptr->content;
+                   while (*t && isspace(*t))
+                       t++;
+                   int i = 0;
+                   while (esn[i] && esn[i] == t[i])
+                       i++;
+                   if (!esn[i] && (!t[i] || isspace(t[i])))
+                       return 1;
                }
-               if (!esn[i] &&  (!*s || isspace(*s)))
-                   return 1;
-               while (*s && !isspace(*s))
-                   s++;
-               t = s;
-           }
        }
     }
     return default_match;
@@ -388,13 +393,18 @@ int Yaz_ProxyConfig::check_esn(xmlNodePtr ptr, Z_RecordComposition *comp)
 int Yaz_ProxyConfig::check_syntax(ODR odr, const char *name,
                                  Odr_oid *syntax, Z_RecordComposition *comp,
                                  char **addinfo,
-                                 char **stylesheet)
+                                 char **stylesheet, char **schema)
 {
     if (stylesheet)
     {
        xfree (*stylesheet);
        *stylesheet = 0;
     }
+    if (schema)
+    {
+       xfree (*schema);
+       *schema = 0;
+    }
 #if HAVE_XSLT
     int syntax_has_matched = 0;
     xmlNodePtr ptr;
@@ -412,6 +422,7 @@ int Yaz_ProxyConfig::check_syntax(ODR odr, const char *name,
            const char *match_error = 0;
            const char *match_marcxml = 0;
            const char *match_stylesheet = 0;
+           const char *match_identifier = 0;
            struct _xmlAttr *attr;
            for (attr = ptr->properties; attr; attr = attr->next)
            {
@@ -427,6 +438,9 @@ int Yaz_ProxyConfig::check_syntax(ODR odr, const char *name,
                if (!strcmp((const char *) attr->name, "stylesheet") &&
                    attr->children && attr->children->type == XML_TEXT_NODE)
                    match_stylesheet = (const char *) attr->children->content;
+               if (!strcmp((const char *) attr->name, "identifier") &&
+                   attr->children && attr->children->type == XML_TEXT_NODE)
+                   match_identifier = (const char *) attr->children->content;
            }
            if (match_type)
            {
@@ -445,10 +459,12 @@ int Yaz_ProxyConfig::check_syntax(ODR odr, const char *name,
                        match = 1;
                }
            }
+           const char *match_schema = 0;
            if (match)
            {
                syntax_has_matched = 1;
-               match = check_esn(ptr->children, comp);
+               match = check_schema(ptr->children, comp, &match_schema,
+                                    match_identifier);
            }
            if (match)
            {
@@ -457,6 +473,14 @@ int Yaz_ProxyConfig::check_syntax(ODR odr, const char *name,
                    xfree(*stylesheet);
                    *stylesheet = xstrdup(match_stylesheet);
                }
+               if (schema && match_schema)
+               {
+                   yaz_log(LOG_LOG, "Match_schema=%s", match_schema);
+                   xfree(*schema);
+                   *schema = xstrdup(match_schema);
+               }
+               else
+                   yaz_log(LOG_LOG, "NO SCHEMA");
                if (match_marcxml)
                {
                    return -1;
index 1ef2f5a..4b280f7 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1998-2004, Index Data.
  * See the file LICENSE for details.
  * 
- * $Id: yaz-proxy.cpp,v 1.77 2004-01-06 21:17:42 adam Exp $
+ * $Id: yaz-proxy.cpp,v 1.78 2004-01-07 11:10:55 adam Exp $
  */
 
 #include <assert.h>
@@ -107,6 +107,7 @@ Yaz_Proxy::Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable,
     m_config = 0;
     m_marcxml_flag = 0;
     m_stylesheet = 0;
+    m_schema = 0;
     m_initRequest_apdu = 0;
     m_initRequest_mem = 0;
     m_apdu_invalid_session = 0;
@@ -135,6 +136,7 @@ Yaz_Proxy::~Yaz_Proxy()
     xfree (m_proxy_authentication);
     xfree (m_optimize);
     xfree (m_stylesheet);
+    xfree (m_schema);
     if (m_s2z_odr_init)
        odr_destroy(m_s2z_odr_init);
     if (m_s2z_odr_search)
@@ -815,7 +817,7 @@ int Yaz_Proxy::send_to_srw_client_ok(int hits, Z_Records *records, int start)
            oident *ent = oid_getentbyoid(r->direct_reference);
            if (r->which == Z_External_octet && ent->value == VAL_TEXT_XML)
            {
-               srw_res->records[i].recordSchema = "http://www.loc.gov/marcxml/";
+               srw_res->records[i].recordSchema = m_schema;
                srw_res->records[i].recordPacking = m_s2z_packing;
                srw_res->records[i].recordData_buf = (char*) 
                    r->u.octet_aligned->buf;
@@ -1447,7 +1449,7 @@ Z_APDU *Yaz_Proxy::handle_syntax_validation(Z_APDU *apdu)
            err = cfg->check_syntax(odr_encode(),
                                    m_default_target,
                                    sr->preferredRecordSyntax, rc,
-                                   &addinfo, &m_stylesheet);
+                                   &addinfo, &m_stylesheet, &m_schema);
        if (err == -1)
        {
            sr->preferredRecordSyntax =
@@ -1479,7 +1481,7 @@ Z_APDU *Yaz_Proxy::handle_syntax_validation(Z_APDU *apdu)
            err = cfg->check_syntax(odr_encode(), m_default_target,
                                    pr->preferredRecordSyntax,
                                    pr->recordComposition,
-                                   &addinfo, &m_stylesheet);
+                                   &addinfo, &m_stylesheet, &m_schema);
        if (err == -1)
        {
            pr->preferredRecordSyntax =