Ursula stuff, mostly in the test client
[yazpp-moved-to-github.git] / src / yaz-ir-assoc.cpp
1 /*
2  * Copyright (c) 1998-2000, Index Data.
3  * See the file LICENSE for details.
4  * 
5  * $Log: yaz-ir-assoc.cpp,v $
6  * Revision 1.15  2001-04-26 12:17:49  heikki
7  * Ursula stuff, mostly in the test client
8  *
9  * Revision 1.14  2000/10/11 11:58:16  adam
10  * Moved header files to include/yaz++. Switched to libtool and automake.
11  * Configure script creates yaz++-config script.
12  *
13  * Revision 1.13  2000/09/06 14:23:45  adam
14  * WIN32 updates.
15  *
16  * Revision 1.12  2000/05/10 11:36:58  ian
17  * Added default parameters for refid to request functions.
18  * Added default parameter for result set name to search and present request.
19  * Commented out forced logging of PDU contents.
20  * Added send_deleteResultSetRequest
21  *
22  * Revision 1.11  1999/12/06 13:52:45  adam
23  * Modified for new location of YAZ header files. Experimental threaded
24  * operation.
25  *
26  * Revision 1.10  1999/04/29 07:33:28  adam
27  * Changed setting of host in connect/proxy setting. YAZ' strtoaddr now
28  * ignores database part of host.
29  *
30  * Revision 1.9  1999/04/28 13:29:14  adam
31  * Yet another fix regarding database settings.
32  *
33  * Revision 1.8  1999/04/28 13:04:03  adam
34  * Fixed setting of proxy otherInfo so that database(s) are removed.
35  *
36  * Revision 1.7  1999/04/21 12:09:01  adam
37  * Many improvements. Modified to proxy server to work with "sessions"
38  * based on cookies.
39  *
40  * Revision 1.6  1999/04/20 10:30:05  adam
41  * Implemented various stuff for client and proxy. Updated calls
42  * to ODR to reflect new name parameter.
43  *
44  * Revision 1.5  1999/04/09 11:46:57  adam
45  * Added object Yaz_Z_Assoc. Much more functional client.
46  */
47
48 #include <assert.h>
49
50 #include <yaz/log.h>
51 #include <yaz++/yaz-ir-assoc.h>
52
53 Yaz_IR_Assoc::Yaz_IR_Assoc(IYaz_PDU_Observable *the_PDU_Observable)
54     : Yaz_Z_Assoc(the_PDU_Observable)
55 {
56     m_num_databaseNames = 0;
57     m_databaseNames = 0;
58     m_preferredRecordSyntax = VAL_NONE;
59     m_elementSetNames = 0;
60     m_lastReceived = 0;
61     m_host = 0;
62     m_proxy = 0;
63     m_cookie = 0;
64     m_log = LOG_DEBUG;
65     const char *db = "Default";
66     set_databaseNames(1, &db);
67 }
68
69 Yaz_IR_Assoc::~Yaz_IR_Assoc()
70 {
71     if (m_elementSetNames)
72         delete [] m_elementSetNames->u.generic;
73     delete [] m_elementSetNames;
74     delete [] m_host;
75     delete [] m_proxy;
76     delete [] m_cookie;
77 }
78
79 void Yaz_IR_Assoc::get_databaseNames (int *num, char ***list)
80 {
81     *num = m_num_databaseNames;
82     *list = m_databaseNames;
83 }
84
85 typedef char *charp;
86 void Yaz_IR_Assoc::set_databaseNames (int num, const char **list)
87 {
88     int i;
89     logf (m_log, "Yaz_IR_Assoc::set_databaseNames num=%d", num);
90     for (i = 0; i<m_num_databaseNames; i++)
91         delete [] m_databaseNames[i];
92     delete [] m_databaseNames;
93     m_num_databaseNames = num;
94
95     m_databaseNames = new char *[num];
96     for (i = 0; i<m_num_databaseNames; i++)
97     {
98         m_databaseNames[i] = new char[strlen(list[i])+1];
99         strcpy(m_databaseNames[i], list[i]);
100     }
101 }
102
103 void Yaz_IR_Assoc::set_databaseNames(const char *dblist, const char *sep)
104 {
105     const char **list = new const char* [strlen(dblist)];
106     char *dbtmp = new char[strlen(dblist)+1];
107     strcpy(dbtmp, dblist);
108     int num = 0;
109     int len = 0;
110     for (char *cp = dbtmp; ; cp++)
111         if (*cp && !strchr(sep, *cp))
112             len++;
113         else
114         {
115             if (len)
116             {
117                 list[num] = cp - len;
118                 num++;
119             }
120             if (!*cp)
121                 break;
122             *cp = '\0';
123             len = 0;
124         }
125     set_databaseNames (num, list);
126     delete [] dbtmp;
127     delete [] list;
128 }
129
130 void Yaz_IR_Assoc::set_preferredRecordSyntax (int value)
131 {
132     m_preferredRecordSyntax = value;
133 }
134
135 void Yaz_IR_Assoc::set_preferredRecordSyntax (const char *syntax)
136 {
137     m_preferredRecordSyntax = VAL_NONE;
138     if (syntax && *syntax)
139         m_preferredRecordSyntax = oid_getvalbyname (syntax);
140 }
141
142 void Yaz_IR_Assoc::get_preferredRecordSyntax (int *value)
143 {
144     *value = m_preferredRecordSyntax;
145 }
146
147 void Yaz_IR_Assoc::get_preferredRecordSyntax (const char **dst)
148 {
149     struct oident ent;
150     ent.proto = PROTO_Z3950;
151     ent.oclass = CLASS_RECSYN;
152     ent.value = (enum oid_value) m_preferredRecordSyntax;
153
154     int oid[OID_SIZE];
155     oid_ent_to_oid (&ent, oid);
156     struct oident *entp = oid_getentbyoid (oid);
157     
158     *dst = entp ? entp->desc : "";
159 }
160
161 void Yaz_IR_Assoc::set_elementSetName (const char *elementSetName)
162 {
163     if (m_elementSetNames)
164         delete [] m_elementSetNames->u.generic;
165     delete m_elementSetNames;
166     m_elementSetNames = 0;
167     if (elementSetName && *elementSetName)
168     {
169         m_elementSetNames = new Z_ElementSetNames;
170         m_elementSetNames->which = Z_ElementSetNames_generic;
171         m_elementSetNames->u.generic = new char[strlen(elementSetName)+1];
172         strcpy (m_elementSetNames->u.generic, elementSetName);
173     }
174 }
175
176 void Yaz_IR_Assoc::get_elementSetName (Z_ElementSetNames **elementSetNames)
177 {
178     *elementSetNames = m_elementSetNames;
179 }
180
181 void Yaz_IR_Assoc::get_elementSetName (const char **elementSetName)
182 {
183     if (!m_elementSetNames ||
184         m_elementSetNames->which != Z_ElementSetNames_generic)
185     {
186         *elementSetName = 0;
187         return;
188     }
189     *elementSetName = m_elementSetNames->u.generic;
190 }
191
192 void Yaz_IR_Assoc::recv_Z_PDU(Z_APDU *apdu)
193 {
194     logf (m_log, "recv_Z_PDU");
195     m_lastReceived = apdu->which;
196     switch (apdu->which)
197     {
198     case Z_APDU_initResponse:
199             logf (m_log, "recv InitResponse");
200             recv_initResponse(apdu->u.initResponse);
201             break;
202     case Z_APDU_initRequest:
203         logf (m_log, "recv InitRequest");
204             recv_initRequest(apdu->u.initRequest);
205         break;
206     case Z_APDU_searchRequest:
207         logf (m_log, "recv searchRequest");
208             recv_searchRequest(apdu->u.searchRequest);
209         break;
210     case Z_APDU_searchResponse:
211             logf (m_log, "recv searchResponse"); 
212             recv_searchResponse(apdu->u.searchResponse);
213             break;
214     case Z_APDU_presentRequest:
215         logf (m_log, "recv presentRequest");
216             recv_presentRequest(apdu->u.presentRequest);
217         break;
218     case Z_APDU_presentResponse:
219         logf (m_log, "recv presentResponse");
220             recv_presentResponse(apdu->u.presentResponse);
221         break;
222     case Z_APDU_extendedServicesResponse:
223         logf (m_log, "recv extendedServiceResponse");
224         recv_extendedServicesResponse(apdu->u.extendedServicesResponse);
225         break;
226     }
227 }
228
229 int Yaz_IR_Assoc::send_searchRequest(Yaz_Z_Query *query,
230                                      char* pResultSetId,
231                                      char* pRefId)
232 {
233     Z_APDU *apdu = create_Z_PDU(Z_APDU_searchRequest);
234     Z_SearchRequest *req = apdu->u.searchRequest;
235     int recordSyntax;
236
237     req->query = query->get_Z_Query();
238     if (!req->query)
239         return -1;
240     get_databaseNames (&req->num_databaseNames, &req->databaseNames);
241     int oid_syntax[OID_SIZE];
242     oident prefsyn;
243     get_preferredRecordSyntax(&recordSyntax);
244     if (recordSyntax != VAL_NONE)
245     {
246         prefsyn.proto = PROTO_Z3950;
247         prefsyn.oclass = CLASS_RECSYN;
248         prefsyn.value = (enum oid_value) recordSyntax;
249         oid_ent_to_oid(&prefsyn, oid_syntax);
250         req->preferredRecordSyntax = oid_syntax;
251     }
252     logf (m_log, "send_searchRequest");
253     assert (req->otherInfo == 0);
254     if (m_cookie)
255     {
256         set_otherInformationString(&req->otherInfo, VAL_COOKIE, 1, m_cookie);
257         assert (req->otherInfo);
258     }
259
260     if ( pRefId )
261     {
262         req->referenceId = getRefID(pRefId);
263     }
264
265     if ( pResultSetId )
266     {
267         req->resultSetName = pResultSetId;
268     }
269
270     return send_Z_PDU(apdu);
271 }
272
273 int Yaz_IR_Assoc::send_presentRequest(int start, 
274                                       int number, 
275                                       char* pResultSetId,
276                                       char* pRefId)
277 {
278     Z_APDU *apdu = create_Z_PDU(Z_APDU_presentRequest);
279     Z_PresentRequest *req = apdu->u.presentRequest;
280
281     req->resultSetStartPoint = &start;
282     req->numberOfRecordsRequested = &number;
283
284     int oid_syntax[OID_SIZE];
285     oident prefsyn;
286     int recordSyntax;
287     get_preferredRecordSyntax (&recordSyntax);
288     if (recordSyntax != VAL_NONE)
289     {
290         prefsyn.proto = PROTO_Z3950;
291         prefsyn.oclass = CLASS_RECSYN;
292         prefsyn.value = (enum oid_value) recordSyntax;
293         oid_ent_to_oid(&prefsyn, oid_syntax);
294         req->preferredRecordSyntax = oid_syntax;
295     }
296     Z_RecordComposition compo;
297     Z_ElementSetNames *elementSetNames;
298     get_elementSetName (&elementSetNames);
299     if (elementSetNames)
300     {
301         req->recordComposition = &compo;
302         compo.which = Z_RecordComp_simple;
303         compo.u.simple = elementSetNames;
304     }
305
306     if (m_cookie)
307         set_otherInformationString(&req->otherInfo, VAL_COOKIE, 1, m_cookie);
308
309     if ( pRefId )
310     {
311         req->referenceId = getRefID(pRefId);
312     }
313
314     if ( pResultSetId )
315     {
316         req->resultSetId = pResultSetId;
317     }
318
319     return send_Z_PDU(apdu);
320 }
321
322 void Yaz_IR_Assoc::set_proxy(const char *str)
323 {
324     delete [] m_proxy;
325     m_proxy = 0;
326     if (str)
327     {
328         m_proxy = new char[strlen(str)+1];
329         strcpy (m_proxy, str);
330     }
331 }
332
333 void Yaz_IR_Assoc::set_cookie(const char *str)
334 {
335     delete [] m_cookie;
336     m_cookie = 0;
337     if (str)
338     {
339         m_cookie = new char[strlen(str)+1];
340         strcpy(m_cookie, str);
341     }
342 }
343
344 const char *Yaz_IR_Assoc::get_cookie()
345 {
346     return m_cookie;
347 }
348
349 void Yaz_IR_Assoc::client(const char *addr)
350 {
351     delete [] m_host;
352     m_host = new char[strlen(addr)+1];
353     strcpy(m_host, addr);
354     const char *dbpart = strchr(m_host, '/');
355     if (dbpart)
356         set_databaseNames (dbpart+1, "+ ");
357     Yaz_Z_Assoc::client(m_proxy ? m_proxy : m_host);
358 }
359
360 const char *Yaz_IR_Assoc::get_proxy()
361 {
362     return m_proxy;
363 }
364
365 const char *Yaz_IR_Assoc::get_host()
366 {
367     return m_host;
368 }
369
370 void Yaz_IR_Assoc::recv_searchRequest(Z_SearchRequest *searchRequest)
371 {
372     Z_APDU *apdu = create_Z_PDU(Z_APDU_searchResponse);
373     send_Z_PDU(apdu);
374 }
375
376 void Yaz_IR_Assoc::recv_presentRequest(Z_PresentRequest *presentRequest)
377 {
378     Z_APDU *apdu = create_Z_PDU(Z_APDU_presentResponse);
379     send_Z_PDU(apdu);
380 }
381
382 void Yaz_IR_Assoc::recv_initRequest(Z_InitRequest *initRequest)
383 {
384     Z_APDU *apdu = create_Z_PDU(Z_APDU_initResponse);
385     send_Z_PDU(apdu);
386 }
387
388 void Yaz_IR_Assoc::recv_searchResponse (Z_SearchResponse *searchResponse)
389 {
390 }
391
392 void Yaz_IR_Assoc::recv_presentResponse (Z_PresentResponse *presentResponse)
393 {
394 }
395
396 void Yaz_IR_Assoc::recv_initResponse(Z_InitResponse *initResponse)
397 {
398 }
399
400 void Yaz_IR_Assoc::recv_extendedServicesResponse(Z_ExtendedServicesResponse *ExtendedServicesResponse)
401 {
402 }
403
404 int Yaz_IR_Assoc::get_lastReceived()
405 {
406     return m_lastReceived;
407 }
408
409 void Yaz_IR_Assoc::set_lastReceived(int lastReceived)
410 {
411     m_lastReceived = lastReceived;
412 }
413
414 int Yaz_IR_Assoc::send_initRequest(char* pRefId)
415 {
416     Z_APDU *apdu = create_Z_PDU(Z_APDU_initRequest);
417     Z_InitRequest *req = apdu->u.initRequest;
418     
419     ODR_MASK_SET(req->options, Z_Options_search);
420     ODR_MASK_SET(req->options, Z_Options_present);
421     ODR_MASK_SET(req->options, Z_Options_namedResultSets);
422     ODR_MASK_SET(req->options, Z_Options_triggerResourceCtrl);
423     ODR_MASK_SET(req->options, Z_Options_scan);
424     ODR_MASK_SET(req->options, Z_Options_sort);
425     ODR_MASK_SET(req->options, Z_Options_extendedServices);
426     ODR_MASK_SET(req->options, Z_Options_delSet);
427
428     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1);
429     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2);
430     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3);
431
432     if ( pRefId )
433     {
434         req->referenceId = getRefID(pRefId);
435     }
436
437     if (m_proxy && m_host)
438         set_otherInformationString(&req->otherInfo, VAL_PROXY, 1, m_host);
439     if (m_cookie)
440         set_otherInformationString(&req->otherInfo, VAL_COOKIE, 1, m_cookie);
441     return send_Z_PDU(apdu);
442 }
443
444 int Yaz_IR_Assoc::send_deleteResultSetRequest(char* pResultSetId, char* pRefId)
445 {
446     char* ResultSetIds[1];
447
448     Z_APDU *apdu = create_Z_PDU(Z_APDU_deleteResultSetRequest);
449     Z_DeleteResultSetRequest *req = apdu->u.deleteResultSetRequest;
450
451     if ( pResultSetId )
452     {
453         *req->deleteFunction = Z_DeleteResultSetRequest_list;
454         req->num_resultSetList = 1;
455         ResultSetIds[0] = pResultSetId;
456         req->resultSetList = ResultSetIds;
457     }
458     else
459     {
460         *req->deleteFunction = Z_DeleteResultSetRequest_all;
461     }
462     
463     if ( pRefId )
464     {
465         req->referenceId = getRefID(pRefId);
466     }
467
468     if (m_proxy && m_host)
469         set_otherInformationString(&req->otherInfo, VAL_PROXY, 1, m_host);
470     if (m_cookie)
471         set_otherInformationString(&req->otherInfo, VAL_COOKIE, 1, m_cookie);
472
473
474     return send_Z_PDU(apdu);
475 }
476
477