Start work on on ZOOM filter
authorAdam Dickmeiss <adam@indexdata.dk>
Mon, 6 Jun 2011 11:43:58 +0000 (13:43 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Mon, 6 Jun 2011 11:43:58 +0000 (13:43 +0200)
This filter is an alternative to z3950_client, just based on ZOOM
instead and with the ability to set ZOOM options.

src/Makefile.am
src/factory_static.cpp
src/filter_zoom.cpp [new file with mode: 0644]
src/filter_zoom.hpp [new file with mode: 0644]
win/makefile

index ddd779e..0f756ea 100644 (file)
@@ -41,6 +41,7 @@ libmetaproxy_la_SOURCES = \
        filter_virt_db.cpp filter_virt_db.hpp \
        filter_z3950_client.cpp filter_z3950_client.hpp \
        filter_zeerex_explain.cpp  filter_zeerex_explain.hpp \
        filter_virt_db.cpp filter_virt_db.hpp \
        filter_z3950_client.cpp filter_z3950_client.hpp \
        filter_zeerex_explain.cpp  filter_zeerex_explain.hpp \
+       filter_zoom.cpp filter_zoom.hpp \
        gduutil.cpp gduutil.hpp \
        origin.cpp \
        package.cpp \
        gduutil.cpp gduutil.hpp \
        origin.cpp \
        package.cpp \
index d34eed6..18f81ea 100644 (file)
@@ -48,6 +48,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include "filter_virt_db.hpp"
 #include "filter_z3950_client.hpp"
 #include "filter_zeerex_explain.hpp"
 #include "filter_virt_db.hpp"
 #include "filter_z3950_client.hpp"
 #include "filter_zeerex_explain.hpp"
+#include "filter_zoom.hpp"
 
 namespace mp = metaproxy_1;
 
 
 namespace mp = metaproxy_1;
 
@@ -75,6 +76,7 @@ mp::FactoryStatic::FactoryStatic()
         &metaproxy_1_filter_virt_db,
         &metaproxy_1_filter_z3950_client,
         &metaproxy_1_filter_zeerex_explain,
         &metaproxy_1_filter_virt_db,
         &metaproxy_1_filter_z3950_client,
         &metaproxy_1_filter_zeerex_explain,
+        &metaproxy_1_filter_zoom,
         0
     };
     int i;
         0
     };
     int i;
diff --git a/src/filter_zoom.cpp b/src/filter_zoom.cpp
new file mode 100644 (file)
index 0000000..b061e1b
--- /dev/null
@@ -0,0 +1,243 @@
+/* This file is part of Metaproxy.
+   Copyright (C) 2005-2011 Index Data
+
+Metaproxy 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
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+Metaproxy is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include "config.hpp"
+#include "filter_zoom.hpp"
+#include <yaz/zoom.h>
+#include <metaproxy/package.hpp>
+#include <metaproxy/util.hpp>
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+
+#include <yaz/zgdu.h>
+
+namespace mp = metaproxy_1;
+namespace yf = mp::filter;
+
+namespace metaproxy_1 {
+    namespace filter {
+        class Zoom::Backend {
+            friend class Impl;
+            std::string zurl;
+            ZOOM_connection m_connection;
+            ZOOM_resultset m_resultset;
+        };
+        class Zoom::Frontend {
+            friend class Impl;
+            Impl *m_p;
+            bool m_is_virtual;
+            bool m_in_use;
+            yazpp_1::GDU m_init_gdu;
+        public:
+            Frontend(Impl *impl);
+            ~Frontend();
+        };
+        class Zoom::Impl {
+        public:
+            Impl();
+            ~Impl();
+            void process(metaproxy_1::Package & package);
+            void configure(const xmlNode * ptr);
+        private:
+            FrontendPtr get_frontend(mp::Package &package);
+            void release_frontend(mp::Package &package);
+
+            std::map<mp::Session, FrontendPtr> m_clients;            
+            boost::mutex m_mutex;
+            boost::condition m_cond_session_ready;
+        };
+    }
+}
+
+// define Pimpl wrapper forwarding to Impl
+yf::Zoom::Zoom() : m_p(new Impl)
+{
+}
+
+yf::Zoom::~Zoom()
+{  // must have a destructor because of boost::scoped_ptr
+}
+
+void yf::Zoom::configure(const xmlNode *xmlnode, bool test_only)
+{
+    m_p->configure(xmlnode);
+}
+
+void yf::Zoom::process(mp::Package &package) const
+{
+    m_p->process(package);
+}
+
+
+// define Implementation stuff
+
+yf::Zoom::Frontend::Frontend(Impl *impl) : 
+    m_p(impl), m_is_virtual(false), m_in_use(true)
+{
+}
+
+yf::Zoom::Frontend::~Frontend()
+{
+}
+
+yf::Zoom::FrontendPtr yf::Zoom::Impl::get_frontend(mp::Package &package)
+{
+    boost::mutex::scoped_lock lock(m_mutex);
+
+    std::map<mp::Session,yf::Zoom::FrontendPtr>::iterator it;
+    
+    while(true)
+    {
+        it = m_clients.find(package.session());
+        if (it == m_clients.end())
+            break;
+        
+        if (!it->second->m_in_use)
+        {
+            it->second->m_in_use = true;
+            return it->second;
+        }
+        m_cond_session_ready.wait(lock);
+    }
+    FrontendPtr f(new Frontend(this));
+    m_clients[package.session()] = f;
+    f->m_in_use = true;
+    return f;
+}
+
+void yf::Zoom::Impl::release_frontend(mp::Package &package)
+{
+    boost::mutex::scoped_lock lock(m_mutex);
+    std::map<mp::Session,yf::Zoom::FrontendPtr>::iterator it;
+    
+    it = m_clients.find(package.session());
+    if (it != m_clients.end())
+    {
+        if (package.session().is_closed())
+        {
+            m_clients.erase(it);
+        }
+        else
+        {
+            it->second->m_in_use = false;
+        }
+        m_cond_session_ready.notify_all();
+    }
+}
+
+yf::Zoom::Impl::Impl()
+{
+}
+
+yf::Zoom::Impl::~Impl()
+{ 
+}
+
+void yf::Zoom::Impl::configure(const xmlNode *xmlnode)
+{
+}
+
+void yf::Zoom::Impl::process(mp::Package &package)
+{
+    FrontendPtr f = get_frontend(package);
+    Z_GDU *gdu = package.request().get();
+
+    if (f->m_is_virtual)
+    {
+        if (gdu->which == Z_GDU_Z3950)
+        {
+            Z_APDU *apdu = gdu->u.z3950;
+            mp::odr odr;
+            
+            package.response() = odr.create_close(
+                apdu,
+                Z_Close_protocolError,
+                "not implemented");
+        }
+        package.session().close();
+    }
+    else if (gdu && gdu->which == Z_GDU_Z3950 && gdu->u.z3950->which ==
+             Z_APDU_initRequest)
+    {
+        Z_InitRequest *req = gdu->u.z3950->u.initRequest;
+        f->m_init_gdu = gdu;
+        
+        mp::odr odr;
+        Z_APDU *apdu = odr.create_initResponse(gdu->u.z3950, 0, 0);
+        Z_InitResponse *resp = apdu->u.initResponse;
+        
+        int i;
+        static const int masks[] = {
+            Z_Options_search,
+            Z_Options_present,
+            -1 
+        };
+        for (i = 0; masks[i] != -1; i++)
+            if (ODR_MASK_GET(req->options, masks[i]))
+                ODR_MASK_SET(resp->options, masks[i]);
+        
+        static const int versions[] = {
+            Z_ProtocolVersion_1,
+            Z_ProtocolVersion_2,
+            Z_ProtocolVersion_3,
+            -1
+        };
+        for (i = 0; versions[i] != -1; i++)
+            if (ODR_MASK_GET(req->protocolVersion, versions[i]))
+                ODR_MASK_SET(resp->protocolVersion, versions[i]);
+            else
+                break;
+        
+        *resp->preferredMessageSize = *req->preferredMessageSize;
+        *resp->maximumRecordSize = *req->maximumRecordSize;
+        
+        package.response() = apdu;
+        f->m_is_virtual = true;
+    }
+    else
+        package.move();
+
+    release_frontend(package);
+}
+
+
+static mp::filter::Base* filter_creator()
+{
+    return new mp::filter::Zoom;
+}
+
+extern "C" {
+    struct metaproxy_1_filter_struct metaproxy_1_filter_zoom = {
+        0,
+        "zoom",
+        filter_creator
+    };
+}
+
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+
diff --git a/src/filter_zoom.hpp b/src/filter_zoom.hpp
new file mode 100644 (file)
index 0000000..f63f738
--- /dev/null
@@ -0,0 +1,57 @@
+/* This file is part of Metaproxy.
+   Copyright (C) 2005-2011 Index Data
+
+Metaproxy 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
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+Metaproxy is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef FILTER_ZOOM_HPP
+#define FILTER_ZOOM_HPP
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <metaproxy/filter.hpp>
+
+namespace metaproxy_1 {
+    namespace filter {
+        class Zoom : public Base {
+            class Impl;
+            class Frontend;
+            class Backend;
+            boost::scoped_ptr<Impl> m_p;
+            typedef boost::shared_ptr<Frontend> FrontendPtr;
+        public:
+            Zoom();
+            ~Zoom();
+            void process(metaproxy_1::Package & package) const;
+            void configure(const xmlNode * ptr, bool test_only);
+        };
+    }
+}
+
+extern "C" {
+    extern struct metaproxy_1_filter_struct metaproxy_1_filter_zoom;
+}
+
+#endif
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+
index d6cf870..b26d462 100644 (file)
@@ -238,6 +238,7 @@ PROJECT_DLL_OBJS = \
         $(OBJDIR)\filter_virt_db.obj \
         $(OBJDIR)\filter_z3950_client.obj \
         $(OBJDIR)\filter_zeerex_explain.obj \
         $(OBJDIR)\filter_virt_db.obj \
         $(OBJDIR)\filter_z3950_client.obj \
         $(OBJDIR)\filter_zeerex_explain.obj \
+        $(OBJDIR)\filter_zoom.obj \
        $(OBJDIR)\gduutil.obj \
        $(OBJDIR)\origin.obj \
        $(OBJDIR)\package.obj \
        $(OBJDIR)\gduutil.obj \
        $(OBJDIR)\origin.obj \
        $(OBJDIR)\package.obj \