X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Ffilter_record_transform.cpp;h=c872e76f18cd66d6db48c7338c48e9e0dba985be;hb=abe840d8d4a289b0cf6221a3e1bc11e640e6c708;hp=f6ddac06c3a86e9b5eb63ab93c05aa3327e2351c;hpb=13ededc67712ac2ecb30677b016b3f6cf4ad4eab;p=metaproxy-moved-to-github.git diff --git a/src/filter_record_transform.cpp b/src/filter_record_transform.cpp index f6ddac0..c872e76 100644 --- a/src/filter_record_transform.cpp +++ b/src/filter_record_transform.cpp @@ -1,5 +1,5 @@ /* This file is part of Metaproxy. - Copyright (C) 2005-2012 Index Data + Copyright (C) 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 @@ -25,6 +25,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include #include +#include + +#include #if HAVE_USEMARCON #include @@ -53,6 +56,8 @@ namespace metaproxy_1 { #if HAVE_USEMARCON struct info_usemarcon { + boost::mutex m_mutex; + char *stage1; char *stage2; @@ -64,6 +69,8 @@ static int convert_usemarcon(void *info, WRBUF record, WRBUF wr_error) { struct info_usemarcon *p = (struct info_usemarcon *) info; + boost::mutex::scoped_lock lock(p->m_mutex); + if (p->usemarcon1) { char *converted; @@ -78,11 +85,11 @@ static int convert_usemarcon(void *info, WRBUF record, WRBUF wr_error) return -1; } p->usemarcon1->GetMarcRecord(converted, convlen); - + if (p->usemarcon2) { p->usemarcon2->SetMarcRecord(converted, convlen); - + res = p->usemarcon2->Convert(); free(converted); if (res != 0) @@ -108,7 +115,7 @@ static void destroy_usemarcon(void *info) delete p->usemarcon2; xfree(p->stage1); xfree(p->stage2); - xfree(p); + delete p; } static void *construct_usemarcon(const xmlNode *ptr, const char *path, @@ -118,7 +125,7 @@ static void *construct_usemarcon(const xmlNode *ptr, const char *path, if (strcmp((const char *) ptr->name, "usemarcon")) return 0; - struct info_usemarcon *p = (struct info_usemarcon *) xmalloc(sizeof(*p)); + struct info_usemarcon *p = new(struct info_usemarcon); p->stage1 = 0; p->stage2 = 0; p->usemarcon1 = 0; @@ -164,7 +171,7 @@ static void type_usemarcon(struct yaz_record_conv_type *t) #endif // define Pimpl wrapper forwarding to Impl - + yf::RecordTransform::RecordTransform() : m_p(new Impl) { } @@ -185,14 +192,14 @@ void yf::RecordTransform::process(mp::Package &package) const } -yf::RecordTransform::Impl::Impl() +yf::RecordTransform::Impl::Impl() { m_retrieval = yaz_retrieval_create(); assert(m_retrieval); } yf::RecordTransform::Impl::~Impl() -{ +{ if (m_retrieval) yaz_retrieval_destroy(m_retrieval); } @@ -207,8 +214,8 @@ void yf::RecordTransform::Impl::configure(const xmlNode *xml_node, // parsing down to retrieval node, which can be any of the children nodes xmlNode *retrieval_node; - for (retrieval_node = xml_node->children; - retrieval_node; + for (retrieval_node = xml_node->children; + retrieval_node; retrieval_node = retrieval_node->next) { if (retrieval_node->type != XML_ELEMENT_NODE) @@ -264,20 +271,20 @@ void yf::RecordTransform::Impl::process(mp::Package &package) const // the effective element set name.. Therefore we can only allow // two cases.. Both equal or absent.. If not, we'll just have to // disable the piggyback! - if (sr_req->smallSetElementSetNames + if (sr_req->smallSetElementSetNames && sr_req->mediumSetElementSetNames && sr_req->smallSetElementSetNames->which == Z_ElementSetNames_generic - && + && sr_req->mediumSetElementSetNames->which == Z_ElementSetNames_generic - && + && !strcmp(sr_req->smallSetElementSetNames->u.generic, sr_req->mediumSetElementSetNames->u.generic)) { input_schema = sr_req->smallSetElementSetNames->u.generic; } - else if (!sr_req->smallSetElementSetNames && + else if (!sr_req->smallSetElementSetNames && !sr_req->mediumSetElementSetNames) ; // input_schema is 0 already else @@ -296,7 +303,7 @@ void yf::RecordTransform::Impl::process(mp::Package &package) const package.move(); return; } - + mp::odr odr_en(ODR_ENCODE); // setting up variables for conversion state @@ -308,7 +315,7 @@ void yf::RecordTransform::Impl::process(mp::Package &package) const const char *backend_schema = 0; Odr_oid *backend_syntax = 0; - int ret_code + int ret_code = yaz_retrieval_request(m_retrieval, input_schema, input_syntax, &match_schema, &match_syntax, @@ -363,7 +370,7 @@ void yf::RecordTransform::Impl::process(mp::Package &package) const if (sr_req) { - if (backend_syntax) + if (backend_syntax) sr_req->preferredRecordSyntax = odr_oiddup(odr_en, backend_syntax); else sr_req->preferredRecordSyntax = 0; @@ -374,7 +381,7 @@ void yf::RecordTransform::Impl::process(mp::Package &package) const = (Z_ElementSetNames *) odr_malloc(odr_en, sizeof(Z_ElementSetNames)); sr_req->smallSetElementSetNames->which = Z_ElementSetNames_generic; - sr_req->smallSetElementSetNames->u.generic + sr_req->smallSetElementSetNames->u.generic = odr_strdup(odr_en, backend_schema); sr_req->mediumSetElementSetNames = sr_req->smallSetElementSetNames; } @@ -386,23 +393,23 @@ void yf::RecordTransform::Impl::process(mp::Package &package) const } else if (pr_req) { - if (backend_syntax) + if (backend_syntax) pr_req->preferredRecordSyntax = odr_oiddup(odr_en, backend_syntax); else pr_req->preferredRecordSyntax = 0; - + if (backend_schema) { - pr_req->recordComposition - = (Z_RecordComposition *) + pr_req->recordComposition + = (Z_RecordComposition *) odr_malloc(odr_en, sizeof(Z_RecordComposition)); - pr_req->recordComposition->which + pr_req->recordComposition->which = Z_RecordComp_simple; - pr_req->recordComposition->u.simple + pr_req->recordComposition->u.simple = (Z_ElementSetNames *) odr_malloc(odr_en, sizeof(Z_ElementSetNames)); pr_req->recordComposition->u.simple->which = Z_ElementSetNames_generic; - pr_req->recordComposition->u.simple->u.generic + pr_req->recordComposition->u.simple->u.generic = odr_strdup(odr_en, backend_schema); } else @@ -413,7 +420,7 @@ void yf::RecordTransform::Impl::process(mp::Package &package) const package.request() = gdu_req; package.move(); - + Z_GDU *gdu_res = package.response().get(); // see if we have a records list to patch! @@ -422,9 +429,9 @@ void yf::RecordTransform::Impl::process(mp::Package &package) const gdu_res->u.z3950->which == Z_APDU_presentResponse) { Z_PresentResponse * pr_res = gdu_res->u.z3950->u.presentResponse; - - if (rc && pr_res - && pr_res->numberOfRecordsReturned + + if (rc && pr_res + && pr_res->numberOfRecordsReturned && *(pr_res->numberOfRecordsReturned) > 0 && pr_res->records && pr_res->records->which == Z_Records_DBOSD) @@ -436,9 +443,9 @@ void yf::RecordTransform::Impl::process(mp::Package &package) const gdu_res->u.z3950->which == Z_APDU_searchResponse) { Z_SearchResponse *sr_res = gdu_res->u.z3950->u.searchResponse; - - if (rc && sr_res - && sr_res->numberOfRecordsReturned + + if (rc && sr_res + && sr_res->numberOfRecordsReturned && *(sr_res->numberOfRecordsReturned) > 0 && sr_res->records && sr_res->records->which == Z_Records_DBOSD) @@ -446,7 +453,7 @@ void yf::RecordTransform::Impl::process(mp::Package &package) const records = sr_res->records->u.databaseOrSurDiagnostics; } } - + if (records) { int i; @@ -455,39 +462,72 @@ void yf::RecordTransform::Impl::process(mp::Package &package) const Z_NamePlusRecord *npr = records->records[i]; if (npr->which == Z_NamePlusRecord_databaseRecord) { - WRBUF output_record = wrbuf_alloc(); + const char *details = 0; + mp::wrbuf output_record; Z_External *r = npr->u.databaseRecord; - int ret_trans = 0; + int ret_trans = -1; if (r->which == Z_External_OPAC) { ret_trans = yaz_record_conv_opac_record(rc, r->u.opac, output_record); + details = yaz_record_conv_get_error(rc); } - else if (r->which == Z_External_octet) + else if (r->which == Z_External_octet) { ret_trans = yaz_record_conv_record(rc, (const char *) - r->u.octet_aligned->buf, + r->u.octet_aligned->buf, r->u.octet_aligned->len, output_record); + details = yaz_record_conv_get_error(rc); } - if (ret_trans == 0) + else { - npr->u.databaseRecord = - z_ext_record_oid(odr_en, match_syntax, - wrbuf_buf(output_record), - wrbuf_len(output_record)); + details = "unsupported record type for record_conv"; } - else + if (ret_trans) { records->records[i] = zget_surrogateDiagRec( odr_en, npr->databaseName, YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS, - yaz_record_conv_get_error(rc)); + details); + } + else + { + if (!oid_oidcmp(match_syntax, yaz_oid_recsyn_opac)) + { + yaz_marc_t mt = yaz_marc_create(); + Z_OPACRecord *opac = 0; + if (yaz_xml_to_opac(mt, output_record.buf(), + output_record.len(), + &opac, 0 /* iconv */, + ((ODR )odr_en)->mem, 0) + && opac) + { + npr->u.databaseRecord = + z_ext_record_oid(odr_en, match_syntax, + (const char *) opac, -1); + } + else + { + records->records[i] = + zget_surrogateDiagRec( + odr_en, npr->databaseName, + YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS, + "XML to OPAC conversion failed"); + } + yaz_marc_destroy(mt); + } + else + { + npr->u.databaseRecord = + z_ext_record_oid(odr_en, match_syntax, + output_record.buf(), + output_record.len()); + } } - wrbuf_destroy(output_record); } } package.response() = gdu_res;