source: trunk/gsdl/src/colservr/z3950parser.cpp@ 11561

Last change on this file since 11561 was 9926, checked in by davidb, 19 years ago

Introduction of Z39.50 Server code for Greenstone. Based on the work of
Chris Martin (2001 approx). Updated to work with newer version of YAZ
library.

  • Property svn:keywords set to Author Date Id Revision
File size: 9.2 KB
Line 
1
2#include "z3950parser.h"
3
4void Z_AttributeList_parse(bend_search_rr *rr, Z_AttributeList *Z, text_t &GSQuery)
5{
6 /*
7 struct Z_AttributeList {
8 int num_attributes;
9 Z_AttributeElement **attributes;
10 };
11 */
12
13 /*
14 struct Z_AttributeElement {
15 Z_AttributeSetId *attributeSet; // OPT
16 int *attributeType;
17 int which;
18 union {
19 int *numeric;
20 Z_ComplexAttribute *complex;
21 #define Z_AttributeValue_numeric 1
22 #define Z_AttributeValue_complex 2
23 } value;
24 };
25 */
26
27
28
29}
30
31void Z_Term_parse(bend_search_rr *rr, Z_Term *Z, text_t &GSQuery)
32{
33 /*
34 struct Z_Term {
35 int which;
36 union {
37 Odr_oct *general;
38 int *numeric;
39 Z_InternationalString *characterString;
40 Odr_oid *oid;
41 char *dateTime;
42 Z_External *external;
43 Z_IntUnit *integerAndUnit;
44 Odr_null *null;
45 #define Z_Term_general 1
46 #define Z_Term_numeric 2
47 #define Z_Term_characterString 3
48 #define Z_Term_oid 4
49 #define Z_Term_dateTime 5
50 #define Z_Term_external 6
51 #define Z_Term_integerAndUnit 7
52 #define Z_Term_null 8
53 } u;
54 };
55 */
56
57 char *term;
58
59 switch(Z->which){
60 case Z_Term_general: {
61 // must copy no more than len bytes from buf, or else previous query terms may be included
62 int buflen = Z->u.general->len;
63 term = new char[buflen+1];
64 memset(term, '\0', buflen+1);
65 strncpy(term, (const char*)(Z->u.general->buf), buflen);
66 GSQuery += term;
67 break; }
68 case Z_Term_numeric:
69 GSQuery += *(Z->u.numeric); // int*
70 break;
71 case Z_Term_characterString:
72 GSQuery += Z->u.characterString; // what is this type?
73 break;
74 case Z_Term_oid:
75 GSQuery += *(Z->u.oid); // int*
76 break;
77 case Z_Term_dateTime:
78 GSQuery += Z->u.dateTime; // char*
79 break;
80 case Z_Term_external:
81 GSQuery += " "; // ignore this for now
82 break;
83 case Z_Term_integerAndUnit:
84 GSQuery += " "; // ignore this for now
85 break;
86 case Z_Term_null:
87 GSQuery += " "; // void
88 break;
89 default:
90 cerr << "Error in Z_Term_parse" << endl;
91 exit(1);
92 }
93}
94
95void Z_ProximityOperator_parse(bend_search_rr *rr, Z_ProximityOperator *Z, text_t &GSQuery)
96{
97 /*
98 struct Z_ProximityOperator {
99 bool_t *exclusion; // OPT
100 int *distance;
101 bool_t *ordered;
102 #define Z_ProximityOperator_Prox_lessThan 1
103 #define Z_ProximityOperator_Prox_lessThanOrEqual 2
104 #define Z_ProximityOperator_Prox_equal 3
105 #define Z_ProximityOperator_Prox_greaterThanOrEqual 4
106 #define Z_ProximityOperator_Prox_greaterThan 5
107 #define Z_ProximityOperator_Prox_notEqual 6
108 int *relationType;
109 int which;
110 union {
111 Z_ProxUnit *known;
112 int *zprivate;
113 #define Z_ProximityOperator_known 1
114 #define Z_ProximityOperator_private 2
115 } u;
116 };
117
118 #define Z_ProxUnit_character 1
119 #define Z_ProxUnit_word 2
120 #define Z_ProxUnit_sentence 3
121 #define Z_ProxUnit_paragraph 4
122 #define Z_ProxUnit_section 5
123 #define Z_ProxUnit_chapter 6
124 #define Z_ProxUnit_document 7
125 #define Z_ProxUnit_element 8
126 #define Z_ProxUnit_subelement 9
127 #define Z_ProxUnit_elementType 10
128 #define Z_ProxUnit_byte 11
129 */
130
131 // Greenstone (actually mgpp) supports proximity, but only
132 // to n words either side.
133 // A more complete implementation of proximity can be added
134 // by parsing the other fields in Z_ProximityOperator.
135 // Note: this only works properly with MGPP collections
136
137 GSQuery += " NEAR";
138 GSQuery += *(Z->distance);
139 GSQuery += " ";
140}
141
142void Z_Operator_parse(bend_search_rr *rr, Z_Operator *Z, text_t &GSQuery)
143{
144 /*
145 struct Z_Operator {
146 int which;
147 union {
148 Odr_null *and;
149 Odr_null *or;
150 Odr_null *and_not;
151 Z_ProximityOperator *prox;
152 #define Z_Operator_and 1
153 #define Z_Operator_or 2
154 #define Z_Operator_and_not 3
155 #define Z_Operator_prox 4
156 } u;
157 };
158 */
159
160 switch(Z->which){
161 case Z_Operator_and:
162 GSQuery += " & ";
163 break;
164 case Z_Operator_or:
165 GSQuery += " | ";
166 break;
167 case Z_Operator_and_not:
168 GSQuery += " ! ";
169 break;
170 case Z_Operator_prox:
171 Z_ProximityOperator_parse(rr, Z->u.prox, GSQuery);
172 break;
173 default:
174 cerr << "Error in Z_Operator_parse" << endl;
175 exit(1);
176 }
177}
178
179void Z_Operand_parse(bend_search_rr *rr, Z_Operand *Z, text_t &GSQuery)
180{
181 /*
182 struct Z_Operand {
183 int which;
184 union {
185 Z_AttributesPlusTerm *attributesPlusTerm;
186 Z_ResultSetId *resultSetId;
187 Z_ResultSetPlusAttributes *resultAttr;
188 #define Z_Operand_APT 1
189 #define Z_Operand_resultSetId 2
190 #define Z_Operand_resultAttr 3
191 } u;
192 };
193 */
194
195 switch(Z->which) {
196 case Z_Operand_APT: {
197 /*
198 struct Z_AttributesPlusTerm {
199 Z_AttributeList *attributes;
200 Z_Term *term;
201 };
202 */
203
204 /*
205 struct Z_AttributeList {
206 int num_attributes;
207 Z_AttributeElement **attributes;
208 };
209 */
210
211 /*
212 struct Z_AttributeElement {
213 Z_AttributeSetId *attributeSet; // OPT
214 int *attributeType;
215 int which;
216 union {
217 int *numeric;
218 Z_ComplexAttribute *complex;
219 #define Z_AttributeValue_numeric 1
220 #define Z_AttributeValue_complex 2
221 } value;
222 };
223 */
224
225 char *term;
226
227 if (Z->u.attributesPlusTerm->attributes->num_attributes > 0) {
228 int Bib1_relation = *(Z->u.attributesPlusTerm->attributes->attributes[0]->attributeType);
229 int Bib1_use = *(Z->u.attributesPlusTerm->attributes->attributes[0]->value.numeric);
230
231 // if use value is 1010 ("Body of text"), is not a fielded search
232 if (Bib1_use == 1010) {
233 // if relation value is 6 ("not"), add a "not" to GSQuery
234 if (Bib1_relation == 6) {
235 GSQuery += "! ";
236 }
237 Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
238 }
239 // for other use values, is a fielded search
240 else {
241 text_t Short;
242 // only add [ ]: if the index exists in the collection,
243 // note: only the index names in the first collection of a
244 // multi-collection search are used at the moment
245 if ((Collection_map[rr->basenames[0]]).getFieldArg(Bib1_use, Short)) {
246 GSQuery += "[";
247 cerr << "Supressing square brackets for the moment!\n";
248
249 Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
250 GSQuery += "]";
251 GSQuery += ":";
252 GSQuery += Short;
253 }
254 // if it doesn't, add it as an unfielded search term
255 else {
256 cerr << "[" << rr->basenames[0] << "]: failed to find index" << endl;
257 Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
258 }
259 }
260 }
261 else {
262 Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
263 }
264 break;
265 }
266 case Z_Operand_resultSetId: {
267 GSQuery += "(";
268 GSQuery += Resultsets[Z->u.resultSetId];
269 GSQuery += ")";
270 break;
271 }
272 case Z_Operand_resultAttr:
273 GSQuery += " "; // ignore this for now
274 break;
275 default:
276 cerr << "Error in Z_Operand_parse" << endl;
277 exit(1);
278 }
279}
280
281void Z_RPNStructure_parse(bend_search_rr *rr, Z_RPNStructure *Z, text_t &GSQuery)
282{
283 /*
284 struct Z_RPNStructure {
285 int which;
286 union {
287 Z_Operand *simple;
288 Z_Complex *complex;
289 #define Z_RPNStructure_simple 1
290 #define Z_RPNStructure_complex 2
291 } u;
292 };
293 */
294
295 switch(Z->which){
296 case Z_RPNStructure_simple:
297 Z_Operand_parse(rr, Z->u.simple, GSQuery);
298 break;
299 case Z_RPNStructure_complex:
300 GSQuery += "(";
301 Z_RPNStructure_parse(rr, Z->u.complex->s1, GSQuery);
302 Z_Operator_parse(rr, Z->u.complex->roperator, GSQuery);
303 Z_RPNStructure_parse(rr, Z->u.complex->s2, GSQuery);
304 GSQuery += ")";
305 break;
306 default:
307 cerr << "Error in Z_RPNStructure_parse" << endl;
308 exit(1);
309 }
310}
311
312text_t ZQueryToGSQuery(bend_search_rr *rr)
313{
314 text_t GSQuery;
315
316 switch(rr->query->which){
317 case Z_Query_type_0:
318 cerr << "querytype = 0" << endl;
319 // this is a void*, pretend it's a Greenstone-type query
320 GSQuery += (char*)(rr->query->u.type_0);
321 break;
322 case Z_Query_type_1: {
323 cerr << "querytype = 1" << endl;
324 /*
325 struct Z_RPNQuery {
326 Z_AttributeSetId *attributeSetId;
327 Z_RPNStructure *RPNStructure;
328 };
329 */
330 // parse attributeSetId
331 cerr << "attributeSetId = ";
332 int c, d = 0;
333 do {
334 c = rr->query->u.type_1->attributeSetId[d];
335 cerr << c;
336 d++;
337 } while (c >= 0);
338 cerr << endl;
339
340 Z_RPNStructure_parse(rr, rr->query->u.type_1->RPNStructure, GSQuery);
341 break; }
342 case Z_Query_type_2: {
343 cerr << "querytype = 2" << endl;
344 // this is just a buf (unsigned char*), pretend it's a Greenstone-type query
345 GSQuery += (char*)(rr->query->u.type_2->buf);
346 break; }
347 case Z_Query_type_100: {
348 cerr << "querytype = 100" << endl;
349 // this is just a buf (unsigned char*), pretend it's a Greenstone-type query
350 GSQuery += (char*)(rr->query->u.type_100->buf);
351 break; }
352 case Z_Query_type_101: {
353 cerr << "querytype = 101" << endl;
354 // check: is this really the same as a type 1 query?
355 Z_RPNStructure_parse(rr, rr->query->u.type_101->RPNStructure, GSQuery);
356 break; }
357 case Z_Query_type_102: {
358 cerr << "querytype = 102" << endl;
359 // this is just a buf (unsigned char*), pretend it's a Greenstone-type query
360 GSQuery += (char*)(rr->query->u.type_102->buf);
361 break; }
362 default: {
363 cerr << "Error in ZQueryToGSQuery" << endl;
364 exit(1); }
365 }
366
367 // override GSQuery (test code)
368 //GSQuery = "[the]:TX";
369
370 cerr << "GSQuery = `" << GSQuery << "'" << endl;
371 return GSQuery;
372}
373
Note: See TracBrowser for help on using the repository browser.