1 /* $Id: filter_query_rewrite.cpp,v 1.3 2006-01-22 00:05:51 marc Exp $
2 Copyright (c) 2005, Index Data.
10 #include "package.hpp"
12 //#include <boost/thread/mutex.hpp>
13 #include <boost/regex.hpp>
16 #include "filter_query_rewrite.hpp"
20 namespace yf = yp2::filter;
24 class QueryRewrite::Rep {
25 //friend class QueryRewrite;
27 void process(yp2::Package &package) const;
28 void configure(const xmlNode * ptr);
30 void rewriteRegex(Z_Query *query) const;
35 // Class QueryRewrite frowarding to class QueryRewrite::Rep
37 yf::QueryRewrite::QueryRewrite() : m_p(new Rep)
41 yf::QueryRewrite::~QueryRewrite()
42 { // must have a destructor because of boost::scoped_ptr
45 void yf::QueryRewrite::process(yp2::Package &package) const
47 m_p->process(package);
50 void yp2::filter::QueryRewrite::configure(const xmlNode *ptr)
56 // Class QueryRewrite::Rep implementation
58 void yf::QueryRewrite::Rep::process(yp2::Package &package) const
60 if (package.session().is_closed())
62 //std::cout << "Got Close.\n";
65 Z_GDU *gdu = package.request().get();
67 if (gdu && gdu->which == Z_GDU_Z3950 && gdu->u.z3950->which ==
70 //std::cout << "Got Z3950 Init PDU\n";
71 //Z_InitRequest *req = gdu->u.z3950->u.initRequest;
72 //package.request() = gdu;
74 else if (gdu && gdu->which == Z_GDU_Z3950 && gdu->u.z3950->which ==
77 //std::cout << "Got Z3950 Search PDU\n";
78 Z_SearchRequest *req = gdu->u.z3950->u.searchRequest;
80 // applying regex query rewriting
81 rewriteRegex(req->query);
83 // fold new query structure into gdu package ..
84 // yp2::util::pqf(odr, gdu->u.z3950, query_out);
85 // question: which odr structure to use in this call ??
86 // memory alignment has to be correct, this is a little tricky ...
87 // I'd rather like to alter the gdu and pack it back using:
88 package.request() = gdu;
90 else if (gdu && gdu->which == Z_GDU_Z3950 && gdu->u.z3950->which ==
93 std::cout << "Got Z3950 Scan PDU\n";
94 //Z_ScanRequest *req = gdu->u.z3950->u.scanRequest;
95 //package.request() = gdu;
101 void yf::QueryRewrite::Rep::rewriteRegex(Z_Query *query) const
103 std::string query_in = yp2::util::zQueryToString(query);
104 //std::cout << "QUERY IN '" << query_in << "'\n";
106 std::string query_out;
110 // make regular expression replacement here
111 std::string expression("@attr 1=4");
112 std::string format("@attr 1=4 @attr 4=3");
113 //std::string expression("the");
114 //std::string format("else");
115 //std::string expression("(<)|(>)|\\r");
116 //std::string format("(?1<)(?2>)");
118 //std::cout << "EXPRESSION '" << expression << "'\n";
119 //std::cout << "FORMAT '" << format << "'\n";
121 rgx.assign(expression.c_str());
127 // see http://www.boost.org/libs/regex/doc/match_flag_type.html
128 //boost::match_flag_type flags = boost::match_default;
129 // boost::format_default
130 // boost::format_perl
131 // boost::format_literal
133 // boost::format_no_copy
134 // boost::format_first_only
136 boost::match_flag_type flags
137 = boost::match_default | boost::format_all;
139 match = regex_match(query_in, rgx, flags);
140 search = regex_search(query_in, rgx, flags);
141 query_out = boost::regex_replace(query_in, rgx, format, flags);
142 //std::cout << "MATCH '" << match << "'\n";
143 //std::cout << "SEARCH '" << search << "'\n";
144 //std::cout << "QUERY OUT '" << query_out << "'\n";
147 catch(boost::regex_error &e)
149 std::cout << "REGEX Error code=" << e.code()
150 << " position=" << e.position() << "\n";
153 //std::cout << "QUERY OUT '" << query_out << "'\n";
154 // still need to fold this new rpn query string into Z_Query structure...
159 void yp2::filter::QueryRewrite::Rep::configure(const xmlNode *filter)
162 //std::cout << "XML node '" << filter->name << "'\n";
163 yp2::xml::check_element_yp2(filter, "filter");
166 = yp2::xml::jump_to_children(filter, XML_ELEMENT_NODE);
169 //std::cout << "XML node '" << regex->name << "'\n";
170 yp2::xml::check_element_yp2(regex, "regex");
173 // const xmlNode* action
174 // = yp2::xml::jump_to_children(regex, XML_ATTRIBUTE_NODE);
176 // std::cout << "XML node '" << action->name << "' '";
177 // std::cout << yp2::xml::get_text(action) << "'\n";
178 // //yp2::xml::check_element_yp2(expression, "expression");
181 // parsing regex expression
183 const xmlNode* expression
184 = yp2::xml::jump_to_children(regex, XML_ELEMENT_NODE);
186 yp2::xml::check_element_yp2(expression, "expression");
187 expr = yp2::xml::get_text(expression);
188 //std::cout << "XML node '" << expression->name << "' '";
189 //std::cout << yp2::xml::get_text(expression) << "'\n";
192 // parsing regex format
194 const xmlNode* format
195 = yp2::xml::jump_to_next(expression, XML_ELEMENT_NODE);
197 yp2::xml::check_element_yp2(format, "format");
198 form = yp2::xml::get_text(format);
199 //std::cout << "XML node '" << format->name << "' '";
200 //std::cout << yp2::xml::get_text(format) << "'\n";
203 // adding configuration
204 if (expr.size() && form.size()){
205 //std::cout << "adding regular expression\n";
208 // moving forward to next regex
209 regex = yp2::xml::jump_to_next(regex, XML_ELEMENT_NODE);
212 // done parsing XML config
216 static yp2::filter::Base* filter_creator()
218 return new yp2::filter::QueryRewrite;
222 struct yp2_filter_struct yp2_filter_query_rewrite = {
230 extern struct yp2_filter_struct yp2_filter_query_rewrite;
237 * indent-tabs-mode: nil
238 * c-file-style: "stroustrup"
240 * vim: shiftwidth=4 tabstop=8 expandtab