added scaffolding for a Z3950 present record transform filter.
[metaproxy-moved-to-github.git] / src / filter_record_transform.cpp
1 /* $Id: filter_record_transform.cpp,v 1.1 2006-10-03 14:04:22 marc Exp $
2    Copyright (c) 2005-2006, Index Data.
3
4    See the LICENSE file for details
5  */
6
7 #include "config.hpp"
8 #include "filter.hpp"
9 #include "filter_record_transform.hpp"
10 #include "package.hpp"
11 #include "util.hpp"
12 #include "gduutil.hpp"
13
14 #include <yaz/zgdu.h>
15
16 //#include <boost/thread/mutex.hpp>
17
18 #include <iostream>
19
20 namespace mp = metaproxy_1;
21 namespace yf = mp::filter;
22
23 namespace metaproxy_1 {
24     namespace filter {
25         class RecordTransform::Impl {
26         public:
27             Impl();
28             ~Impl();
29             void process(metaproxy_1::Package & package) const;
30             void configure(const xmlNode * xml_node);
31         private:
32
33         };
34     }
35 }
36
37 // define Pimpl wrapper forwarding to Impl
38  
39 yf::RecordTransform::RecordTransform() : m_p(new Impl)
40 {
41 }
42
43 yf::RecordTransform::~RecordTransform()
44 {  // must have a destructor because of boost::scoped_ptr
45 }
46
47 void yf::RecordTransform::configure(const xmlNode *xmlnode)
48 {
49     m_p->configure(xmlnode);
50 }
51
52 void yf::RecordTransform::process(mp::Package &package) const
53 {
54     m_p->process(package);
55 }
56
57
58 // define Implementation stuff
59
60
61
62 yf::RecordTransform::Impl::Impl()
63 {
64 }
65
66 yf::RecordTransform::Impl::~Impl()
67
68 }
69
70 void yf::RecordTransform::Impl::configure(const xmlNode *xml_node)
71 {
72 //    for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next)
73 //     {
74 //         if (xml_node->type != XML_ELEMENT_NODE)
75 //             continue;
76 //         if (!strcmp((const char *) xml_node->name, "target"))
77 //         {
78 //             std::string route = mp::xml::get_route(xml_node);
79 //             std::string target = mp::xml::get_text(xml_node);
80 //             std::cout << "route=" << route << " target=" << target << "\n";
81 //             m_p->m_target_route[target] = route;
82 //         }
83 //         else if (!strcmp((const char *) xml_node->name, "hideunavailable"))
84 //         {
85 //             m_p->m_hide_unavailable = true;
86 //         }
87 //         else
88 //         {
89 //             throw mp::filter::FilterException
90 //                 ("Bad element " 
91 //                  + std::string((const char *) xml_node->name)
92 //                  + " in virt_db filter");
93 //         }
94 //     }
95 }
96
97 void yf::RecordTransform::Impl::process(mp::Package &package) const
98 {
99
100     Z_GDU *gdu = package.request().get();
101     
102     // only working on z3950 present packages
103     if (!gdu 
104         || !(gdu->which == Z_GDU_Z3950) 
105         || !(gdu->u.z3950->which == Z_APDU_presentRequest))
106     {
107         package.move();
108         return;
109     }
110     
111     // getting original present request
112     Z_PresentRequest *front_pr = gdu->u.z3950->u.presentRequest;
113
114     // setting up ODR's for memory during encoding/decoding
115     mp::odr odr_de(ODR_DECODE);  
116     mp::odr odr_en(ODR_ENCODE);
117
118     // now packaging the z3950 backend present request
119     Package back_package(package.session(), package.origin());
120     back_package.copy_filter(package);
121  
122     Z_APDU *apdu = zget_APDU(odr_en, Z_APDU_presentRequest);
123
124     assert(apdu->u.presentRequest);
125
126     // z3950'fy start record position
127     //if ()
128     //    *(apdu->u.presentRequest->resultSetStartPoint) 
129     //        =
130     
131     // z3950'fy number of records requested 
132     //if ()
133     //    *(apdu->u.presentRequest->numberOfRecordsRequested) 
134      
135     // z3950'fy record syntax
136     //if()
137     //(apdu->u.presentRequest->preferredRecordSyntax)
138     //    = yaz_oidval_to_z3950oid (odr_en, CLASS_RECSYN, VAL_TEXT_XML);
139
140     // z3950'fy record schema
141     //if ()
142     // {
143     //     apdu->u.presentRequest->recordComposition 
144     //         = (Z_RecordComposition *) 
145     //           odr_malloc(odr_en, sizeof(Z_RecordComposition));
146     //     apdu->u.presentRequest->recordComposition->which 
147     //         = Z_RecordComp_simple;
148     //     apdu->u.presentRequest->recordComposition->u.simple 
149     //         = build_esn_from_schema(odr_en, 
150     //                                 (const char *) sr_req->recordSchema); 
151     // }
152
153     // attaching Z3950 package to filter chain
154     back_package.request() = apdu;
155
156     // std::cout << "z3950_present_request " << *apdu << "\n";   
157
158     // sending backend package
159     back_package.move();
160
161    //check successful Z3950 present response
162     Z_GDU *back_gdu = back_package.response().get();
163     if (!back_gdu || back_gdu->which != Z_GDU_Z3950 
164         || back_gdu->u.z3950->which != Z_APDU_presentResponse
165         || !back_gdu->u.z3950->u.presentResponse)
166
167     {
168         std::cout << "record-transform: error back present\n";
169         package.session().close();
170         return;
171     }
172     
173
174     // everything fine, continuing
175     // std::cout << "z3950_present_request OK\n";
176     // std::cout << "back z3950 " << *back_gdu << "\n";
177
178
179     return;
180 }
181
182
183 static mp::filter::Base* filter_creator()
184 {
185     return new mp::filter::RecordTransform;
186 }
187
188 extern "C" {
189     struct metaproxy_1_filter_struct metaproxy_1_filter_record_transform = {
190         0,
191         "record_transform",
192         filter_creator
193     };
194 }
195
196
197 /*
198  * Local variables:
199  * c-basic-offset: 4
200  * indent-tabs-mode: nil
201  * c-file-style: "stroustrup"
202  * End:
203  * vim: shiftwidth=4 tabstop=8 expandtab
204  */