Add path to configure method of filter.
[metaproxy-moved-to-github.git] / src / filter_zoom.cpp
index a611381..b625898 100644 (file)
@@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include <yaz/srw.h>
 #include <metaproxy/package.hpp>
 #include <metaproxy/util.hpp>
+#include <metaproxy/xmlutil.hpp>
 #include "torus.hpp"
 
 #include <libxslt/xsltutils.h>
@@ -60,6 +61,7 @@ namespace metaproxy_1 {
             std::string element_set;
             std::string record_encoding;
             std::string transform_xsl_fname;
+            std::string urlRecipe;
             bool use_turbomarc;
             bool piggyback;
             CCL_bibset ccl_bibset;
@@ -152,7 +154,8 @@ yf::Zoom::~Zoom()
 {  // must have a destructor because of boost::scoped_ptr
 }
 
-void yf::Zoom::configure(const xmlNode *xmlnode, bool test_only)
+void yf::Zoom::configure(const xmlNode *xmlnode, bool test_only,
+                         const char *path)
 {
     m_p->configure(xmlnode, test_only);
 }
@@ -400,6 +403,11 @@ yf::Zoom::SearchablePtr yf::Zoom::Impl::parse_torus_record(const xmlNode *ptr)
             s->transform_xsl_fname = mp::xml::get_text(ptr);
         }
         else if (!strcmp((const char *) ptr->name,
+                         "urlRecipe"))
+        {
+            s->urlRecipe = mp::xml::get_text(ptr);
+        }
+        else if (!strcmp((const char *) ptr->name,
                          "useTurboMarc"))
         {
             ; // useTurboMarc is ignored
@@ -530,6 +538,7 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
     if (m_backend && m_backend->m_frontend_database == database)
         return m_backend;
 
+    const char *sru_proxy = 0;
     std::string db_args;
     std::string torus_db;
     size_t db_arg_pos = database.find(',');
@@ -628,19 +637,34 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
     {
         // A CF target
         b->set_option("user", sptr->cfAuth.c_str());
-        if (authentication.length() && db_args.length() == 0)
+        if (db_args.length() == 0)
         {
-            // no database (auth) args specified already.. and the
-            // Torus authentication has it.. Generate the args that CF
-            // understands..
-            size_t found = authentication.find('/');
-            if (found != std::string::npos)
+            if (authentication.length())
+            {
+                // no database (auth) args specified already.. and the
+                // Torus authentication has it.. Generate the args that CF
+                // understands..
+                size_t found = authentication.find('/');
+                if (found != std::string::npos)
+                {
+                    db_args += "user=" + mp::util::uri_encode(authentication.substr(0, found))
+                        + "&password=" + mp::util::uri_encode(authentication.substr(found+1));
+                }
+                else
+                    db_args += "user=" + mp::util::uri_encode(authentication);
+            }
+            if (sptr->cfProxy.length())
             {
-                db_args += "user=" + mp::util::uri_encode(authentication.substr(0, found))
-                    + "&password=" + mp::util::uri_encode(authentication.substr(found+1));
+                if (db_args.length())
+                    db_args += "&";
+                db_args += "proxy=" + mp::util::uri_encode(sptr->cfProxy);
             }
-            else
-                db_args += "user=" + mp::util::uri_encode(authentication);
+        }
+        if (sptr->cfSubDb.length())
+        {
+            if (db_args.length())
+                db_args += "&";
+            db_args += "subdatabase=" + mp::util::uri_encode(sptr->cfSubDb);
         }
     }
     else
@@ -664,6 +688,8 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
                     param_user = value;
                 else if (!strcmp(name, "password"))
                     param_password = value;
+                else if (!strcmp(name, "proxy"))
+                    sru_proxy = value;
                 else
                 {
                     BackendPtr notfound;
@@ -692,18 +718,9 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
                 b->set_option("user", authentication.c_str());
         }
     }
-    if (sptr->cfProxy.length())
-    {
-        if (db_args.length())
-            db_args += "&";
-        db_args += "proxy=" + mp::util::uri_encode(sptr->cfProxy);
-    }
-    if (sptr->cfSubDb.length())
-    {
-        if (db_args.length())
-            db_args += "&";
-        db_args += "subdatabase=" + mp::util::uri_encode(sptr->cfSubDb);
-    }
+
+    if (sru_proxy)
+        b->set_option("proxy", sru_proxy);
 
     std::string url;
     if (sptr->sru.length())
@@ -777,7 +794,10 @@ Z_Records *yf::Zoom::Frontend::get_records(Odr_int start,
         if (b->sptr->request_syntax.length())
         {
             syntax_name = b->sptr->request_syntax.c_str();
-            if (strcmp(syntax_name, "xml"))
+            const Odr_oid *syntax_oid = 
+                yaz_string_to_oid(yaz_oid_std(), CLASS_RECSYN, syntax_name);
+            if (!oid_oidcmp(syntax_oid, yaz_oid_recsyn_usmarc)
+                || !oid_oidcmp(syntax_oid, yaz_oid_recsyn_opac))
                 assume_marc8_charset = true;
         }
     }
@@ -845,6 +865,7 @@ Z_Records *yf::Zoom::Frontend::get_records(Odr_int start,
                 }
                 
                 int rec_len;
+                xmlChar *xmlrec_buf = 0;
                 const char *rec_buf = ZOOM_record_get(recs[i], rec_type_str,
                                                       &rec_len);
                 if (rec_buf && b->xsp && enable_pz2_transform)
@@ -856,13 +877,39 @@ Z_Records *yf::Zoom::Frontend::get_records(Odr_int start,
                         rec_res = xsltApplyStylesheet(b->xsp, rec_doc, 0);
 
                         if (rec_res)
-                            xsltSaveResultToString((xmlChar **) &rec_buf, &rec_len,
+                            xsltSaveResultToString(&xmlrec_buf, &rec_len,
                                                    rec_res, b->xsp);
+                        rec_buf = (const char *) xmlrec_buf;
+                        xmlFreeDoc(rec_doc);
+                        xmlFreeDoc(rec_res);
                     }
                 }
 
                 if (rec_buf)
                 {
+                    xmlDoc *doc = xmlParseMemory(rec_buf, rec_len);
+                    std::string res = 
+                        mp::xml::url_recipe_handle(doc, b->sptr->urlRecipe);
+                    if (res.length())
+                    {
+                        xmlNode *ptr = xmlDocGetRootElement(doc);
+                        while (ptr && ptr->type != XML_ELEMENT_NODE)
+                            ptr = ptr->next;
+                        xmlNode *c = 
+                            xmlNewChild(ptr, 0, BAD_CAST "generated-url", 0);
+                        xmlNode * t = xmlNewText(BAD_CAST res.c_str());
+                        xmlAddChild(c, t);
+
+                        if (xmlrec_buf)
+                            xmlFree(xmlrec_buf);
+
+                        xmlDocDumpMemory(doc, &xmlrec_buf, &rec_len);
+                        rec_buf = (const char *) xmlrec_buf;
+                    }
+                    xmlFreeDoc(doc);
+                }
+                if (rec_buf)
+                {
                     npr = (Z_NamePlusRecord *) odr_malloc(odr, sizeof(*npr));
                     npr->databaseName = odr_database;
                     npr->which = Z_NamePlusRecord_databaseRecord;
@@ -876,6 +923,8 @@ Z_Records *yf::Zoom::Frontend::get_records(Odr_int start,
                         YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS,
                         rec_type_str);
                 }
+                if (xmlrec_buf)
+                    xmlFree(xmlrec_buf);
             }
             else
             {