87void yf::CQLtoRPN::Impl::configure(
const xmlNode *xmlnode,
const char *path)
89 int no_conversions = 0;
90 for (
const xmlNode *node = xmlnode->children; node; node = node->next)
92 if (node->type != XML_ELEMENT_NODE)
94 if (strcmp((
const char *) node->name,
"conversion"))
96 throw mp::filter::FilterException(
"Bad element "
97 + std::string((
const char *)
100 const struct _xmlAttr *attr;
101 for (attr = node->properties; attr; attr = attr->next)
103 if (!strcmp((
const char *) attr->name,
"file"))
105 std::string fname = mp::xml::get_text(attr);
107 if (!yaz_filepath_resolve(fname.c_str(), path, 0, fullpath))
108 throw mp::filter::FilterException(
"Could not open " + fname);
110 if (!m_cql2rpn.parse_spec_file(fullpath, &error))
112 throw mp::filter::FilterException(
"Bad or missing "
113 "CQL to RPN configuration "
118 else if (!strcmp((
const char *) attr->name,
"key"))
120 std::string key = mp::xml::get_text(attr);
121 std::string val = mp::xml::get_text(node);
122 if (m_cql2rpn.define_pattern(key.c_str(), val.c_str()))
123 throw mp::filter::FilterException(
124 "Bad CQL to RPN pattern: " + key +
"=" + val);
127 else if (!strcmp((
const char *) attr->name,
"reverse"))
129 reverse = mp::xml::get_bool(attr->children, 0);
132 throw mp::filter::FilterException(
133 "Bad attribute " + std::string((
const char *)
137 if (no_conversions == 0)
139 throw mp::filter::FilterException(
"Missing conversion configuration "
140 "for filter cql_rpn");
144void yf::CQLtoRPN::Impl::process(mp::Package &package)
146 Z_GDU *gdu = package.request().get();
148 if (gdu && gdu->which == Z_GDU_Z3950 && gdu->u.z3950->which ==
149 Z_APDU_searchRequest)
151 Z_APDU *apdu_req = gdu->u.z3950;
152 Z_SearchRequest *sr = gdu->u.z3950->u.searchRequest;
153 if (reverse && sr->query && sr->query->which == Z_Query_type_1)
157 WRBUF cql = wrbuf_alloc();
159 int r = m_cql2rpn.rpn2cql_transform(sr->query->u.type_1, cql,
164 odr.create_searchResponse(apdu_req, r, addinfo);
165 package.response() = f_apdu;
170 Z_External *ext = (Z_External *)
171 odr_malloc(odr,
sizeof(*ext));
172 ext->direct_reference = odr_oiddup(odr,
173 yaz_oid_userinfo_cql);
174 ext->indirect_reference = 0;
176 ext->which = Z_External_CQL;
177 ext->u.cql = odr_strdup(odr, wrbuf_cstr(cql));
179 sr->query->which = Z_Query_type_104;
180 sr->query->u.type_104 = ext;
182 package.request() = gdu;
186 if (!reverse && sr->query && sr->query->which == Z_Query_type_104 &&
187 sr->query->u.type_104->which == Z_External_CQL)
190 Z_RPNQuery *rpnquery = 0;
193 int r = m_cql2rpn.query_transform(sr->query->u.type_104->u.cql,
199 odr.create_searchResponse(
201 YAZ_BIB1_PERMANENT_SYSTEM_ERROR,
202 "cql_rpn: missing CQL to RPN configuration");
203 package.response() = f_apdu;
208 int error_code = yaz_diag_srw_to_bib1(r);
211 odr.create_searchResponse(apdu_req, error_code, addinfo);
212 package.response() = f_apdu;
218 sr->query->which = Z_Query_type_1;
219 sr->query->u.type_1 = rpnquery;
220 package.request() = gdu;