metaproxy 1.22.1
filter_zeerex_explain.cpp
Go to the documentation of this file.
1/* This file is part of Metaproxy.
2 Copyright (C) Index Data
3
4Metaproxy is free software; you can redistribute it and/or modify it under
5the terms of the GNU General Public License as published by the Free
6Software Foundation; either version 2, or (at your option) any later
7version.
8
9Metaproxy is distributed in the hope that it will be useful, but WITHOUT ANY
10WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17*/
18
19#include "config.hpp"
21#include <metaproxy/package.hpp>
22#include <metaproxy/util.hpp>
23#include "gduutil.hpp"
24#include "sru_util.hpp"
25
26#include <yaz/zgdu.h>
27#include <yaz/z-core.h>
28#include <yaz/srw.h>
29#include <yaz/pquery.h>
30
31#include <boost/thread/mutex.hpp>
32
33#include <iostream>
34#include <sstream>
35#include <string>
36#include <algorithm>
37#include <map>
38
39namespace mp = metaproxy_1;
40namespace mp_util = metaproxy_1::util;
41namespace yf = mp::filter;
42
43
44namespace metaproxy_1 {
45 namespace filter {
47 public:
48 void configure(const xmlNode *xmlnode);
49 void process(metaproxy_1::Package &package);
50 private:
51 std::map<std::string, const xmlNode *> m_database_explain;
52 };
53 }
54}
55
56yf::ZeeRexExplain::ZeeRexExplain() : m_p(new Impl)
57{
58}
59
60yf::ZeeRexExplain::~ZeeRexExplain()
61{ // must have a destructor because of boost::scoped_ptr
62}
63
64void yf::ZeeRexExplain::configure(const xmlNode *xmlnode, bool test_only,
65 const char *path)
66{
67 m_p->configure(xmlnode);
68}
69
70void yf::ZeeRexExplain::process(mp::Package &package) const
71{
72 m_p->process(package);
73}
74
75void yf::ZeeRexExplain::Impl::configure(const xmlNode *confignode)
76{
77 const xmlNode * dbnode;
78
79 for (dbnode = confignode->children; dbnode; dbnode = dbnode->next){
80 if (dbnode->type != XML_ELEMENT_NODE)
81 continue;
82
83 std::string database;
84 mp::xml::check_element_mp(dbnode, "database");
85
86 for (struct _xmlAttr *attr = dbnode->properties;
87 attr; attr = attr->next){
88
89 mp::xml::check_attribute(attr, "", "name");
90 database = mp::xml::get_text(attr);
91
92 const xmlNode *explainnode;
93 for (explainnode = dbnode->children;
94 explainnode; explainnode = explainnode->next){
95 if (explainnode->type != XML_ELEMENT_NODE)
96 continue;
97 if (explainnode)
98 break;
99 }
100 // assigning explain node to database name - no check yet
101 m_database_explain.insert(std::make_pair(database, explainnode));
102 }
103 }
104}
105
106
107void yf::ZeeRexExplain::Impl::process(mp::Package &package)
108{
109 Z_GDU *zgdu_req = package.request().get();
110
111 // ignoring all non HTTP_Request packages
112 if (zgdu_req == 0 || zgdu_req->which != Z_GDU_HTTP_Request)
113 {
114 package.move();
115 return;
116 }
117
118 // only working on HTTP_Request packages now
119 mp::odr odr_de(ODR_DECODE);
120 Z_SRW_PDU *sru_pdu_req = 0;
121
122 mp::odr odr_en(ODR_ENCODE);
123 Z_SRW_PDU *sru_pdu_res = yaz_srw_get(odr_en, Z_SRW_explain_response);
124
125 // finding correct SRU database and explain XML node fragment from config
127
128 const xmlNode *explainnode = 0;
129 std::map<std::string, const xmlNode *>::iterator idbexp;
130 idbexp = m_database_explain.find(sruinfo.database);
131
132 if (idbexp == m_database_explain.end())
133 {
134 // need to emit error ?? or just let package pass ??
135 package.move();
136 return;
137 }
138 explainnode = idbexp->second;
139
140 Z_SOAP *soap = 0;
141 char *charset = 0;
142 char *stylesheet = 0;
143 Z_SRW_diagnostic *diagnostic = 0;
144 int num_diagnostic = 0;
145
146 if ((sru_pdu_req = mp_util::decode_sru_request(
147 package, odr_de, odr_en,
148 &diagnostic, &num_diagnostic, &soap,
149 charset)) == 0)
150 {
151 mp_util::build_sru_explain(package, odr_en, sru_pdu_res,
152 sruinfo, explainnode);
153 mp_util::build_sru_response(package, odr_en, soap,
154 sru_pdu_res, charset, stylesheet);
155 package.session().close();
156 return;
157 }
158 if (sru_pdu_req->which != Z_SRW_explain_request)
159 {
160 // Let pass all other SRU actions
161 package.move();
162 return;
163 }
164 Z_SRW_explainRequest *er_req = sru_pdu_req->u.explain_request;
165
166 sru_pdu_res->u.explain_response->diagnostics = diagnostic;
167 sru_pdu_res->u.explain_response->num_diagnostics = num_diagnostic;
168
169 mp_util::build_sru_explain(package, odr_en, sru_pdu_res,
170 sruinfo, explainnode, er_req);
171 mp_util::build_sru_response(package, odr_en, soap,
172 sru_pdu_res, charset, stylesheet);
173}
174
175
176
177static mp::filter::Base* filter_creator()
178{
179 return new mp::filter::ZeeRexExplain;
180}
181
182extern "C" {
183 struct metaproxy_1_filter_struct metaproxy_1_filter_zeerex_explain = {
184 0,
185 "zeerex_explain",
187 };
188}
189
190
191/*
192 * Local variables:
193 * c-basic-offset: 4
194 * c-file-style: "Stroustrup"
195 * indent-tabs-mode: nil
196 * End:
197 * vim: shiftwidth=4 tabstop=8 expandtab
198 */
199
void process(metaproxy_1::Package &package)
std::map< std::string, const xmlNode * > m_database_explain
static mp::filter::Base * filter_creator()
struct metaproxy_1_filter_struct metaproxy_1_filter_zeerex_explain
Z_SRW_PDU * decode_sru_request(metaproxy_1::Package &package, metaproxy_1::odr &odr_de, metaproxy_1::odr &odr_en, Z_SRW_diagnostic **diagnostic, int *num_diagnostic, Z_SOAP **soap, char *charset)
SRUServerInfo get_sru_server_info(metaproxy_1::Package &package)
bool build_sru_response(metaproxy_1::Package &package, metaproxy_1::odr &odr_en, Z_SOAP *soap, const Z_SRW_PDU *sru_pdu_res, char *charset, const char *stylesheet)
void build_sru_explain(metaproxy_1::Package &package, metaproxy_1::odr &odr_en, Z_SRW_PDU *sru_pdu_res, SRUServerInfo sruinfo, const xmlNode *explain=0, Z_SRW_explainRequest const *er_req=0)
Definition sru_util.cpp:89