metaproxy  1.21.0
Public Member Functions | Private Attributes | List of all members
metaproxy_1::filter::QueryRewrite::Rep Class Reference
Collaboration diagram for metaproxy_1::filter::QueryRewrite::Rep:
Collaboration graph

Public Member Functions

 Rep ()
 
 ~Rep ()
 
void process (mp::Package &package) const
 
void configure (const xmlNode *ptr, bool test_only, const char *path)
 

Private Attributes

xsltStylesheetPtr m_stylesheet
 
std::string charset_from
 
std::string charset_to
 

Detailed Description

Definition at line 41 of file filter_query_rewrite.cpp.

Constructor & Destructor Documentation

◆ Rep()

mp::filter::QueryRewrite::Rep::Rep ( )

Definition at line 56 of file filter_query_rewrite.cpp.

◆ ~Rep()

mp::filter::QueryRewrite::Rep::~Rep ( )

Definition at line 60 of file filter_query_rewrite.cpp.

61 {
62  if (m_stylesheet)
63  xsltFreeStylesheet(m_stylesheet);
64 }

Member Function Documentation

◆ configure()

void mp::filter::QueryRewrite::Rep::configure ( const xmlNode *  ptr,
bool  test_only,
const char *  path 
)

Definition at line 154 of file filter_query_rewrite.cpp.

156 {
157  for (ptr = ptr->children; ptr; ptr = ptr->next)
158  {
159  if (ptr->type != XML_ELEMENT_NODE)
160  continue;
161 
162  if (mp::xml::is_element_mp(ptr, "xslt"))
163  {
164  if (m_stylesheet)
165  {
166  throw mp::filter::FilterException
167  ("Only one xslt element allowed in query_rewrite filter");
168  }
169 
170  std::string fname;
171 
172  for (struct _xmlAttr *attr = ptr->properties;
173  attr; attr = attr->next)
174  {
175  mp::xml::check_attribute(attr, "", "stylesheet");
176  fname = mp::xml::get_text(attr);
177  }
178 
179  if (0 == fname.size())
180  throw mp::filter::FilterException
181  ("Attribute <xslt stylesheet=\""
182  + fname
183  + "\"> needs XSLT stylesheet path content"
184  + " in query_rewrite filter");
185 
186  char fullpath[1024];
187  char *cp = yaz_filepath_resolve(fname.c_str(), path, 0, fullpath);
188  if (!cp)
189  {
190  throw mp::filter::FilterException("Cannot read XSLT " + fname);
191  }
192 
193  m_stylesheet = xsltParseStylesheetFile(BAD_CAST cp);
194  if (!m_stylesheet)
195  {
196  throw mp::filter::FilterException
197  ("Failed to read XSLT stylesheet '"
198  + fname
199  + "' in query_rewrite filter");
200  }
201  }
202  else if (mp::xml::is_element_mp(ptr, "charset"))
203  {
204  for (struct _xmlAttr *attr = ptr->properties;
205  attr; attr = attr->next)
206  {
207  if (!strcmp((const char *) attr->name, "from"))
208  {
209  charset_from = mp::xml::get_text(attr);
210  }
211  else if (!strcmp((const char *) attr->name, "to"))
212  {
213  charset_to = mp::xml::get_text(attr);
214  }
215  else
216  throw mp::filter::FilterException
217  ("Invalid attribute inside charset inside "
218  "query_rewrite filter");
219  }
220  }
221  else
222  {
223  throw mp::filter::FilterException
224  ("Bad element "
225  + std::string((const char *) ptr->name)
226  + " in query_rewrite filter");
227  }
228  }
229 }

◆ process()

void mp::filter::QueryRewrite::Rep::process ( mp::Package &  package) const

Definition at line 85 of file filter_query_rewrite.cpp.

86 {
87  Z_GDU *gdu = package.request().get();
88 
89  if (gdu && gdu->which == Z_GDU_Z3950)
90  {
91  Z_APDU *apdu_req = gdu->u.z3950;
92  if (apdu_req->which == Z_APDU_searchRequest)
93  {
94  int error_code = 0;
95  const char *addinfo = 0;
96  mp::odr odr;
97  Z_SearchRequest *req = apdu_req->u.searchRequest;
98 
99  if (m_stylesheet)
100  {
101  xmlDocPtr doc_input = 0;
102  yaz_query2xml(req->query, &doc_input);
103 
104  if (doc_input)
105  {
106  xmlDocPtr doc_res = xsltApplyStylesheet(m_stylesheet,
107  doc_input, 0);
108  if (!doc_res)
109  {
110  error_code = YAZ_BIB1_MALFORMED_QUERY;
111  addinfo = "XSLT transform failed for query";
112  }
113  else
114  {
115  const xmlNode *root_element = xmlDocGetRootElement(doc_res);
116  yaz_xml2query(root_element, &req->query, odr,
117  &error_code, &addinfo);
118  xmlFreeDoc(doc_res);
119  }
120  xmlFreeDoc(doc_input);
121  }
122  }
123  if (!error_code && charset_to.length() && charset_from.length() &&
124  (req->query->which == Z_Query_type_1
125  || req->query->which == Z_Query_type_101))
126  {
127  yaz_iconv_t cd = yaz_iconv_open(charset_to.c_str(),
128  charset_from.c_str());
129  if (cd)
130  {
131  int r = yaz_query_charset_convert_rpnquery_check(
132  req->query->u.type_1, odr, cd);
133  yaz_iconv_close(cd);
134  if (r)
135  { /* query could not be char converted */
136  error_code = YAZ_BIB1_MALFORMED_QUERY;
137  addinfo = "could not convert query to target charset";
138  }
139  }
140  }
141  if (error_code)
142  {
143  Z_APDU *f_apdu =
144  odr.create_searchResponse(apdu_req, error_code, addinfo);
145  package.response() = f_apdu;
146  return;
147  }
148  package.request() = gdu;
149  }
150  }
151  package.move();
152 }

Member Data Documentation

◆ charset_from

std::string metaproxy_1::filter::QueryRewrite::Rep::charset_from
private

Definition at line 50 of file filter_query_rewrite.cpp.

◆ charset_to

std::string metaproxy_1::filter::QueryRewrite::Rep::charset_to
private

Definition at line 51 of file filter_query_rewrite.cpp.

◆ m_stylesheet

xsltStylesheetPtr metaproxy_1::filter::QueryRewrite::Rep::m_stylesheet
private

Definition at line 49 of file filter_query_rewrite.cpp.


The documentation for this class was generated from the following file: