Statistics
| Revision:

svn-gvsig-desktop / trunk / applications / appCatalogYNomenclatorClient / src / es / gva / cit / catalogClient / protocols / Z3950OriginBean.java @ 3613

History | View | Annotate | Download (28 KB)

1

    
2
// Title:       A Synchronous bean for implementing a Z3950 Origin
3
// @version:    $Id: Z3950OriginBean.java 3613 2006-01-12 13:53:14Z jorpiell $
4
// Copyright:   Copyright (C) 1999,2000 Knowledge Integration Ltd.
5
// @author:     Ian Ibbotson (ibbo@k-int.com)
6
// Company:     KI
7
// Description:
8
//
9
//
10
// This program is free software; you can redistribute it and/or
11
// modify it under the terms of the GNU Lesser General Public License
12
// as published by the Free Software Foundation; either version 2.1 of
13
// the license, or (at your option) any later version.
14
//
15
// This program is distributed in the hope that it will be useful,
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
// GNU Lesser General Public License for more details.
19
//
20
// You should have received a copy of the GNU Lesser General Public License
21
// along with this program; if not, write to the Free Software
22
// Foundation, Inc., 59 Temple Place - Suite
23
// 330, Boston, MA  02111-1307, USA.
24
//
25
package es.gva.cit.catalogClient.protocols;
26
import com.k_int.IR.InvalidQueryException;
27
import com.k_int.IR.QueryModel;
28
import com.k_int.IR.SearchException;
29
import com.k_int.IR.TimeoutExceededException;
30
import com.k_int.codec.util.OIDRegister;
31
import com.k_int.gen.AsnUseful.EXTERNAL_type;
32
import com.k_int.gen.RecordSyntax_explain.CategoryInfo_type;
33
import com.k_int.gen.RecordSyntax_explain.CategoryList_type;
34
import com.k_int.gen.RecordSyntax_explain.DatabaseInfo_type;
35
import com.k_int.gen.RecordSyntax_explain.Explain_Record_type;
36
import com.k_int.gen.Z39_50_APDU_1995.DefaultDiagFormat_type;
37
import com.k_int.gen.Z39_50_APDU_1995.DiagRec_type;
38
import com.k_int.gen.Z39_50_APDU_1995.InitializeResponse_type;
39
import com.k_int.gen.Z39_50_APDU_1995.NamePlusRecord_type;
40
import com.k_int.gen.Z39_50_APDU_1995.PDU_type;
41
import com.k_int.gen.Z39_50_APDU_1995.PresentResponse_type;
42
import com.k_int.gen.Z39_50_APDU_1995.Records_type;
43
import com.k_int.gen.Z39_50_APDU_1995.ScanResponse_type;
44
import com.k_int.gen.Z39_50_APDU_1995.SearchRequest_type;
45
import com.k_int.gen.Z39_50_APDU_1995.SearchResponse_type;
46
import com.k_int.gen.Z39_50_APDU_1995.record_inline13_type;
47
import com.k_int.util.LoggingFacade.LogContextFactory;
48
import com.k_int.util.LoggingFacade.LoggingContext;
49
import com.k_int.util.RPNQueryRep.RootNode;
50
import com.k_int.z3950.util.APDUEvent;
51
import com.k_int.z3950.util.APDUListener;
52
import com.k_int.z3950.util.GenericEventToOriginListenerAdapter;
53
import com.k_int.z3950.util.PDUTypeAvailableSemaphore;
54
import com.k_int.z3950.util.ReferencedPDUAvaialableSemaphore;
55
import com.k_int.z3950.util.ZEndpoint;
56
import java.util.Enumeration;
57
import java.util.HashMap;
58
import java.util.Hashtable;
59
import java.util.Properties;
60
import java.util.Vector;
61
// for OID Register
62
// Used to represent query structures
63

    
64
/**
65
 * SynchronousOriginBean : A Z3950 session that trys to behave as a synchronous local resource. IE
66
 * Z39.50 Requests wait for their corresponding response before returning (Or time out)
67
 * 
68
 * 
69
 * @version: $Id: Z3950OriginBean.java 3613 2006-01-12 13:53:14Z jorpiell $
70
 * @author: Ian Ibbotson (ian.ibbotson@k-int.com)
71
 */
72
public class Z3950OriginBean implements APDUListener {
73

    
74
/**
75
 * 
76
 * 
77
 */
78
    public static final int NO_CONNECTION = 1;
79

    
80
/**
81
 * 
82
 * 
83
 */
84
    public static final int CONNECTING = 2;
85

    
86
/**
87
 * 
88
 * 
89
 */
90
    public static final int CONNECTED = 3;
91

    
92
/**
93
 * 
94
 * 
95
 */
96
    public static final String NO_RS_NAME = "default";
97
/**
98
 * 
99
 * 
100
 */
101
    protected static LoggingContext cat = LogContextFactory.getContext(
102
            "SynchronousOriginBean");
103
/**
104
 * 
105
 * 
106
 */
107
    ZEndpoint assoc = null;
108
/**
109
 * 
110
 * 
111
 */
112
    OIDRegister reg = null;
113

    
114
/**
115
 * 
116
 * 
117
 */
118
    Vector db_names = new Vector();
119

    
120
/**
121
 * 
122
 * 
123
 */
124
    String record_syntax = "sutrs";
125
// Default is to ask for brief sutrs records
126

    
127
/**
128
 * 
129
 * 
130
 */
131
    int session_status = NO_CONNECTION;
132

    
133
/**
134
 * 
135
 * 
136
 */
137
    private HashMap responses = new HashMap();
138

    
139
/**
140
 * 
141
 * 
142
 */
143
    private Hashtable dbinfo = new Hashtable();
144

    
145
/**
146
 * 
147
 * 
148
 */
149
    private boolean supports_named_result_sets = false;
150

    
151
/**
152
 * 
153
 * 
154
 */
155
    public  Z3950OriginBean() {        
156
        db_names.add("Default");
157
        // The OIDRegister static initialiser now looks for an oidreg.default file via the classloader
158
        // instead of having lots of messy static data in this file. You can add new OID's to that file
159
        // (See the OIDRegister class in the A2J Project) Or by calling the OIDRegConfigurator load 
160
        // method with the name of the resource to be loaded.
161
        reg = OIDRegister.getRegister();
162
    } 
163

    
164
/**
165
 * 
166
 * 
167
 * 
168
 * @return 
169
 */
170
    public int getSessionStatus() {        
171
        return session_status;
172
    } 
173

    
174
/**
175
 * 
176
 * 
177
 * 
178
 * @param i 
179
 */
180
    public void setSessionStatus(int i) {        
181
        session_status = i;
182
    } 
183

    
184
/**
185
 * 
186
 * 
187
 * 
188
 * @param record_syntax 
189
 */
190
    public void setRecordSyntax(String record_syntax) {        
191
        this.record_syntax = record_syntax;
192
    } 
193

    
194
/**
195
 * 
196
 * 
197
 * 
198
 * @return 
199
 */
200
    public String getRecordSyntax() {        
201
        return record_syntax;
202
    } 
203

    
204
/**
205
 * 
206
 * 
207
 */
208
    public void clearAllDatabases() {        
209
        db_names.clear();
210
    } 
211

    
212
/**
213
 * 
214
 * 
215
 * 
216
 * @param dbname 
217
 */
218
    public void addDatatabse(String dbname) {        
219
        db_names.add(dbname);
220
    } 
221

    
222
/**
223
 * 
224
 * 
225
 */
226
    public void disconnect() {        
227
        if (null != assoc) {
228
            System.err.println("Closing existing listener");
229
            try {
230
                assoc.shutdown();
231
            } catch (java.io.IOException ioe) {
232
                ioe.printStackTrace();
233
            }
234
        }
235
    } 
236

    
237
/**
238
 * 
239
 * 
240
 * 
241
 * @return 
242
 * @param hostname 
243
 * @param portnum 
244
 */
245
    public InitializeResponse_type connect(String hostname, String portnum) {        
246
        // Close down any outstanding assoc
247
        disconnect();
248
        return connect(hostname, portnum, 0, null, null, null);
249
    } 
250
// 0 = none, 1=Anonymous, 2=open, 3=idpass
251
// for open, the access string, for idpass, the id
252
// group
253
// password
254

    
255
/**
256
 * 
257
 * 
258
 * 
259
 * @return 
260
 * @param hostname 
261
 * @param portnum 
262
 * @param auth_type 
263
 * @param principal 
264
 * @param group 
265
 * @param credentials 
266
 */
267
    public InitializeResponse_type connect(String hostname, String portnum, int auth_type, String principal, String group, String credentials) {        
268
        System.err.println("Connect");
269
        InitializeResponse_type retval = null;
270
        try {
271
            disconnect();
272
            Properties p = new Properties();
273
            p.setProperty("ServiceHost", hostname);
274
            p.setProperty("ServicePort", portnum);
275
            p.setProperty("service_auth_type", "" + auth_type);
276
            if (principal != null) {
277
                p.setProperty("service_user_principal", principal);
278
            }
279
            if (group != null) {
280
                p.setProperty("service_user_group", group);
281
            }
282
            if (credentials != null) {
283
                p.setProperty("service_user_credentials", credentials);
284
            }
285
            cat.debug(p.toString());
286
            System.out.println("Create listener & encoder");
287
            assoc = new ZEndpoint(p);
288
            // Convert incoming observer/observable notifications into PDU notifications.
289
            assoc.getPDUAnnouncer().addObserver(new GenericEventToOriginListenerAdapter(
290
                    this));
291
            // Look out for the init response
292
            PDUTypeAvailableSemaphore s = new PDUTypeAvailableSemaphore(PDU_type.initresponse_CID,
293
                    assoc.getPDUAnnouncer());
294
            assoc.start();
295
            try {
296
                s.waitForCondition(20000); // Wait up to 20 seconds for an init response
297
                retval = (InitializeResponse_type) s.the_pdu.o;
298
            } catch (Exception e) {
299
            } finally {
300
                s.destroy();
301
            }
302
        } catch (Exception e) {
303
            e.printStackTrace();
304
        }
305
        return retval;
306
    } 
307

    
308
/**
309
 * 
310
 * 
311
 * 
312
 * @return 
313
 * @param query 
314
 * @param refid 
315
 * @param setname 
316
 */
317
    public SearchResponse_type sendSearch(QueryModel query, String refid, String setname) throws SearchException, InvalidQueryException {        
318
        return sendSearch(query, refid, setname, "F");
319
    } 
320

    
321
/**
322
 * 
323
 * 
324
 * 
325
 * @return 
326
 * @param query 
327
 * @param refid 
328
 * @param setname 
329
 * @param elements 
330
 */
331
    public SearchResponse_type sendSearch(QueryModel query, String refid, String setname, String elements) throws SearchException, InvalidQueryException {        
332
        System.err.println("Sending search request....");
333
        SearchResponse_type retval = null;
334
        if (refid == null) {
335
            refid = assoc.genRefid("Search");
336
        }
337
        // ReferencedPDUAvaialableSemaphore s = new ReferencedPDUAvaialableSemaphore(refid, assoc.getPDUAnnouncer() );
338
        PDUTypeAvailableSemaphore s = new PDUTypeAvailableSemaphore(PDU_type.searchresponse_CID,
339
                assoc.getPDUAnnouncer());
340
        try {
341
            if (cat.isDebugEnabled()) {
342
                cat.debug("Sending Search request, setname=" + setname +
343
                    " syntax=" + record_syntax);
344
            }
345
            assoc.sendSearchRequest(db_names, query, refid, 3, 5, 10, true, // ssub, lslb, mspn
346
                ((supports_named_result_sets == true) ? setname : NO_RS_NAME), // Result set name
347
                elements, elements, reg.oidByName(record_syntax));
348
            s.waitForCondition(20000); // Wait up to 20 seconds for a message of type SearchResponse
349
            retval = (SearchResponse_type) s.the_pdu.o;
350
            if (retval.records != null) {
351
                if (retval.records.which == Records_type.nonsurrogatediagnostic_CID) {
352
                    // Record contains defaultDiagFormat object
353
                    DefaultDiagFormat_type d = (DefaultDiagFormat_type) retval.records.o;
354
                    if (d.addinfo != null) {
355
                        throw new SearchException("Diagnostic [" + d.condition +
356
                            "] Additional Info : " + d.addinfo.o, retval);
357
                    } else {
358
                        throw new SearchException("Diagnostic [" + d.condition +
359
                            "] no additional info", retval);
360
                    }
361
                } else if (retval.records.which == Records_type.multiplenonsurdiagnostics_CID) {
362
                    // Record contains DiagRec ( May have externally defined info )
363
                    DiagRec_type d = (DiagRec_type) retval.records.o;
364
                    if (d.which == DiagRec_type.defaultformat_CID) {
365
                        DefaultDiagFormat_type dd = (DefaultDiagFormat_type) d.o;
366
                        throw new SearchException("Diagnostic [" +
367
                            dd.condition + "] Additional Info : " +
368
                            dd.addinfo.o, retval);
369
                    } else {
370
                        throw new SearchException("Externally defined diagnostic record",
371
                            retval);
372
                    }
373
                } else {
374
                    System.err.println("Search has valid piggyback records");
375
                }
376
            }
377
        } catch (java.io.IOException ioe) {
378
            // Problem with comms sending PDU...
379
            ioe.printStackTrace();
380
        } catch (TimeoutExceededException tee) {
381
            tee.printStackTrace();
382
        } finally {
383
            s.destroy();
384
        }
385
        return retval;
386
    } 
387

    
388
/**
389
 * 
390
 * 
391
 * 
392
 * @return 
393
 * @param query 
394
 */
395
    public SearchResponse_type sendSearch(RootNode query) throws SearchException, InvalidQueryException {        
396
        SearchResponse_type retval = null;
397
        String refid = assoc.genRefid("Search");
398
        ReferencedPDUAvaialableSemaphore s = new ReferencedPDUAvaialableSemaphore(refid,
399
                assoc.getPDUAnnouncer());
400
        try {
401
            assoc.sendSearchRequest(db_names, query, refid, 10, 20, 10, true,
402
                "simple", "f", "f", reg.oidByName(record_syntax));
403
            s.waitForCondition(20000); // Wait up to 20 seconds for a response
404
            retval = (SearchResponse_type) s.the_pdu.o;
405
        } catch (java.io.IOException ioe) {
406
            ioe.printStackTrace();
407
        } catch (TimeoutExceededException tee) {
408
            tee.printStackTrace();
409
        } finally {
410
            s.destroy();
411
        }
412
        if (retval.records != null) {
413
            if (retval.records.which == Records_type.nonsurrogatediagnostic_CID) {
414
                // Record contains defaultDiagFormat object
415
                DefaultDiagFormat_type d = (DefaultDiagFormat_type) retval.records.o;
416
                throw new SearchException("Diagnostic [" + d.condition +
417
                    "] Additional Info : " + d.addinfo.o, retval);
418
            } else if (retval.records.which == Records_type.multiplenonsurdiagnostics_CID) {
419
                // Record contains DiagRec ( May have externally defined info )
420
                DiagRec_type d = (DiagRec_type) retval.records.o;
421
                if (d.which == DiagRec_type.defaultformat_CID) {
422
                    DefaultDiagFormat_type dd = (DefaultDiagFormat_type) d.o;
423
                    throw new SearchException("Diagnostic [" + dd.condition +
424
                        "] Additional Info : " + dd.addinfo.o, retval);
425
                } else {
426
                    throw new SearchException("Externally defined diagnostic record",
427
                        retval);
428
                }
429
            } else {
430
                System.err.println("Search seems has valid piggyback records");
431
            }
432
        }
433
        return retval;
434
    } 
435

    
436
/**
437
 * Alternate sendSearch that simply passes along a search request PDU. Added for proxy server.
438
 * 
439
 * 
440
 * @return 
441
 * @param req 
442
 */
443
    public SearchResponse_type sendSearch(PDU_type req) throws SearchException, InvalidQueryException {        
444
        SearchResponse_type retval = null;
445
        SearchRequest_type search_req = (SearchRequest_type) req.o;
446
        ReferencedPDUAvaialableSemaphore s = new ReferencedPDUAvaialableSemaphore(new String(
447
                    search_req.referenceId), assoc.getPDUAnnouncer());
448
        try {
449
            assoc.encodeAndSend(req);
450
            s.waitForCondition(20000); // Wait up to 20 seconds for a response
451
            retval = (SearchResponse_type) s.the_pdu.o;
452
        } catch (java.io.IOException ioe) {
453
            ioe.printStackTrace();
454
        } catch (TimeoutExceededException tee) {
455
            tee.printStackTrace();
456
        } finally {
457
            s.destroy();
458
        }
459
        return retval;
460
    } 
461

    
462
/**
463
 * 
464
 * 
465
 * 
466
 * @return 
467
 * @param qm 
468
 */
469
    public ScanResponse_type sendScan(QueryModel qm) {        
470
        ScanResponse_type retval = null;
471
        PDUTypeAvailableSemaphore s = new PDUTypeAvailableSemaphore(PDU_type.scanresponse_CID,
472
                assoc.getPDUAnnouncer());
473
        try {
474
            assoc.sendScanRequest("scan", db_names, qm, 0, 10, 5);
475
            s.waitForCondition(20000);
476
            retval = (ScanResponse_type) s.the_pdu.o;
477
        } catch (TimeoutExceededException tee) {
478
            tee.printStackTrace();
479
        } catch (Exception e) {
480
            e.printStackTrace();
481
        } finally {
482
            s.destroy();
483
        }
484
        System.err.println("Done scan request");
485
        return retval;
486
    } 
487
// Notification Handlers
488

    
489
/**
490
 * 
491
 * 
492
 * 
493
 * @param e 
494
 */
495
    public void incomingAPDU(APDUEvent e) {        
496
        // We don't care about this
497
        // System.err.println("Incoming APDU notification");
498
    } 
499

    
500
/**
501
 * 
502
 * 
503
 * 
504
 * @return 
505
 * @param start 
506
 * @param count 
507
 * @param element_set_name 
508
 * @param setname 
509
 */
510
    public PresentResponse_type sendPresent(long start, long count, String element_set_name, String setname) {        
511
        PresentResponse_type retval = null;
512
        String refid = assoc.genRefid("Present");
513
        PDUTypeAvailableSemaphore s = new PDUTypeAvailableSemaphore(PDU_type.presentresponse_CID,
514
                assoc.getPDUAnnouncer());
515
        // ReferencedPDUAvaialableSemaphore s = new ReferencedPDUAvaialableSemaphore(refid, assoc.getPDUAnnouncer() );
516
        try {
517
            if (cat.isDebugEnabled()) {
518
                cat.debug("Sending present request for " + count +
519
                    " records starting at " + start + ", setname=" + setname +
520
                    " syntax=" + record_syntax);
521
            }
522
            assoc.sendPresentRequest(refid,
523
                ((supports_named_result_sets == true) ? setname : NO_RS_NAME),
524
                start, count, record_syntax, element_set_name);
525
            s.waitForCondition(20000); // Wait up to 20 seconds for a response
526
            retval = (PresentResponse_type) s.the_pdu.o;
527
        } catch (TimeoutExceededException tee) {
528
            tee.printStackTrace();
529
        } catch (Exception e) {
530
            e.printStackTrace();
531
        } finally {
532
            s.destroy();
533
        }
534
        System.err.println("Done present request");
535
        return retval;
536
    } 
537

    
538
/**
539
 * 
540
 * 
541
 * 
542
 * @param e 
543
 */
544
    public void incomingInitRequest(APDUEvent e) {        
545
        cat.debug("Incoming InitRequest");
546
        // Preparation for synchronous Retrieval API
547
        notifyAll();
548
    } 
549

    
550
/**
551
 * 
552
 * 
553
 * 
554
 * @param e 
555
 */
556
    public void incomingInitResponse(APDUEvent e) {        
557
        InitializeResponse_type init_response = (InitializeResponse_type) (e.getPDU().o);
558
        responses.put(init_response.referenceId, init_response);
559
        session_status = CONNECTED;
560
        cat.debug("Incoming init response " + init_response.referenceId);
561
        if (init_response.result.booleanValue() == true) {
562
            if (init_response.options.isSet(14)) {
563
                cat.debug("Target supports named result sets");
564
            } else {
565
                cat.debug("Target does not support named result sets");
566
                supports_named_result_sets = false;
567
            }
568
        }
569
        synchronized (this) {
570
            notifyAll();
571
        }
572
    } 
573

    
574
/**
575
 * 
576
 * 
577
 * 
578
 * @param e 
579
 */
580
    public void incomingSearchRequest(APDUEvent e) {        
581
        cat.debug("\nIncoming SearchRequest");
582
        // Preparation for synchronous Retrieval API
583
        synchronized (this) {
584
            notifyAll();
585
        }
586
    } 
587

    
588
/**
589
 * 
590
 * 
591
 * 
592
 * @param e 
593
 */
594
    public void incomingSearchResponse(APDUEvent e) {        
595
        SearchResponse_type search_response = (SearchResponse_type) e.getPDU().o;
596
        responses.put(search_response.referenceId, search_response);
597
        cat.debug("Incoming search response " + search_response.referenceId);
598
        synchronized (this) {
599
            notifyAll();
600
        }
601
    } 
602

    
603
/**
604
 * 
605
 * 
606
 * 
607
 * @param e 
608
 */
609
    public void incomingPresentRequest(APDUEvent e) {        
610
        cat.debug("Incoming PresentResponse");
611
        // Preparation for synchronous Retrieval API
612
        synchronized (this) {
613
            notifyAll();
614
        }
615
    } 
616

    
617
/**
618
 * 
619
 * 
620
 * 
621
 * @param e 
622
 */
623
    public void incomingPresentResponse(APDUEvent e) {        
624
        PresentResponse_type present_response = (PresentResponse_type) e.getPDU().o;
625
        responses.put(present_response.referenceId, present_response);
626
        synchronized (this) {
627
            notifyAll();
628
        }
629
    } 
630

    
631
/**
632
 * 
633
 * 
634
 * 
635
 * @param e 
636
 */
637
    public void incomingDeleteResultSetRequest(APDUEvent e) {        
638
        // Preparation for synchronous Retrieval API
639
        synchronized (this) {
640
            notifyAll();
641
        }
642
    } 
643

    
644
/**
645
 * 
646
 * 
647
 * 
648
 * @param e 
649
 */
650
    public void incomingDeleteResultSetResponse(APDUEvent e) {        
651
        cat.debug("Incoming DeleteResultSetResponse");
652
        // Preparation for synchronous Retrieval API
653
        synchronized (this) {
654
            notifyAll();
655
        }
656
    } 
657

    
658
/**
659
 * 
660
 * 
661
 * 
662
 * @param e 
663
 */
664
    public void incomingAccessControlRequest(APDUEvent e) {        
665
        // Preparation for synchronous Retrieval API
666
        synchronized (this) {
667
            notifyAll();
668
        }
669
    } 
670

    
671
/**
672
 * 
673
 * 
674
 * 
675
 * @param e 
676
 */
677
    public void incomingAccessControlResponse(APDUEvent e) {        
678
        System.err.println("Incoming AccessControlResponse");
679
        // Preparation for synchronous Retrieval API
680
        synchronized (this) {
681
            notifyAll();
682
        }
683
    } 
684

    
685
/**
686
 * 
687
 * 
688
 * 
689
 * @param e 
690
 */
691
    public void incomingResourceControlRequest(APDUEvent e) {        
692
        // Preparation for synchronous Retrieval API
693
        synchronized (this) {
694
            notifyAll();
695
        }
696
    } 
697

    
698
/**
699
 * 
700
 * 
701
 * 
702
 * @param e 
703
 */
704
    public void incomingResourceControlResponse(APDUEvent e) {        
705
        System.err.println("Incoming ResourceControlResponse");
706
        // Preparation for synchronous Retrieval API
707
        synchronized (this) {
708
            notifyAll();
709
        }
710
    } 
711

    
712
/**
713
 * 
714
 * 
715
 * 
716
 * @param e 
717
 */
718
    public void incomingTriggerResourceControlRequest(APDUEvent e) {        
719
        // Preparation for synchronous Retrieval API
720
        synchronized (this) {
721
            notifyAll();
722
        }
723
    } 
724

    
725
/**
726
 * 
727
 * 
728
 * 
729
 * @param e 
730
 */
731
    public void incomingResourceReportRequest(APDUEvent e) {        
732
        System.err.println("Incoming ResourceReportResponse");
733
        // Preparation for synchronous Retrieval API
734
        synchronized (this) {
735
            notifyAll();
736
        }
737
    } 
738

    
739
/**
740
 * 
741
 * 
742
 * 
743
 * @param e 
744
 */
745
    public void incomingResourceReportResponse(APDUEvent e) {        
746
        // Preparation for synchronous Retrieval API
747
        synchronized (this) {
748
            notifyAll();
749
        }
750
    } 
751

    
752
/**
753
 * 
754
 * 
755
 * 
756
 * @param e 
757
 */
758
    public void incomingScanRequest(APDUEvent e) {        
759
        System.err.println("Incoming ScanResponse");
760
        // Preparation for synchronous Retrieval API
761
        synchronized (this) {
762
            notifyAll();
763
        }
764
    } 
765

    
766
/**
767
 * 
768
 * 
769
 * 
770
 * @param e 
771
 */
772
    public void incomingScanResponse(APDUEvent e) {        
773
        // Preparation for synchronous Retrieval API
774
        synchronized (this) {
775
            notifyAll();
776
        }
777
    } 
778

    
779
/**
780
 * 
781
 * 
782
 * 
783
 * @param e 
784
 */
785
    public void incomingSortRequest(APDUEvent e) {        
786
        System.err.println("Incoming SortResponse");
787
        // Preparation for synchronous Retrieval API
788
        synchronized (this) {
789
            notifyAll();
790
        }
791
    } 
792

    
793
/**
794
 * 
795
 * 
796
 * 
797
 * @param e 
798
 */
799
    public void incomingSortResponse(APDUEvent e) {        
800
        // Preparation for synchronous Retrieval API
801
        synchronized (this) {
802
            notifyAll();
803
        }
804
    } 
805

    
806
/**
807
 * 
808
 * 
809
 * 
810
 * @param e 
811
 */
812
    public void incomingSegmentRequest(APDUEvent e) {        
813
        System.err.println("Incoming SegmentResponse");
814
        // Preparation for synchronous Retrieval API
815
        synchronized (this) {
816
            notifyAll();
817
        }
818
    } 
819

    
820
/**
821
 * 
822
 * 
823
 * 
824
 * @param e 
825
 */
826
    public void incomingExtendedServicesRequest(APDUEvent e) {        
827
        // Preparation for synchronous Retrieval API
828
        synchronized (this) {
829
            notifyAll();
830
        }
831
    } 
832

    
833
/**
834
 * 
835
 * 
836
 * 
837
 * @param e 
838
 */
839
    public void incomingExtendedServicesResponse(APDUEvent e) {        
840
        System.err.println("Incoming ExtendedServicesResponse");
841
        // Preparation for synchronous Retrieval API
842
        synchronized (this) {
843
            notifyAll();
844
        }
845
    } 
846

    
847
/**
848
 * 
849
 * 
850
 * 
851
 * @param e 
852
 */
853
    public void incomingClose(APDUEvent e) {        
854
        // Preparation for synchronous Retrieval API
855
        synchronized (this) {
856
            notifyAll();
857
        }
858
    } 
859

    
860
/**
861
 * 
862
 * 
863
 */
864
    public void doExplain() throws SearchException, InvalidQueryException {        
865
        clearAllDatabases();
866
        addDatatabse("IR-Explain-1");
867
        setRecordSyntax("explain");
868
        SearchResponse_type r = sendSearch(new com.k_int.IR.QueryModels.PrefixString(
869
                    "@attrset exp-1 @attr 1=1 categoryList"), "exp", "expset");
870
        if (r.searchStatus.booleanValue()) {
871
            // OK, Our search for a category list in the explain database seems to have worked...
872
            // Figure out what useful info we can from the available categories
873
            if (r.resultCount.intValue() == 1) {
874
                // That's good, only one category list
875
                CategoryList_type cl = null;
876
                if (r.numberOfRecordsReturned.intValue() == 1) {
877
                    // Even better, it looks like the category list has been piggybacked
878
                    if (r.records.which == Records_type.responserecords_CID) {
879
                        Vector response_records = (Vector) r.records.o;
880
                        NamePlusRecord_type npr = (NamePlusRecord_type) response_records.get(0);
881
                        System.err.println("Got record from " + npr.name);
882
                        switch (npr.record.which) {
883
                        case record_inline13_type.retrievalrecord_CID: {
884
                            EXTERNAL_type et = (EXTERNAL_type) npr.record.o;
885
                            Object o = et.encoding.o;
886
                            System.err.println("Got retrieval record");
887
                            if (o instanceof Explain_Record_type) {
888
                                cl = (CategoryList_type) (((Explain_Record_type) o).o);
889
                                for (int i = 0; i < cl.categories.size();
890
                                        i++) {
891
                                    CategoryInfo_type ci = (CategoryInfo_type) cl.categories.get(i);
892
                                    System.err.println("Aviailable category : " +
893
                                        ci.category);
894
                                    if (null != ci.category) {
895
                                        if (ci.category.equals("DatabaseInfo")) {
896
                                            explainDatabaseInfo();
897
                                        }
898
                                    }
899
                                }
900
                            }
901
                            break;
902
                        }
903
                        default:
904
                            System.err.println(
905
                                "Unhandled name plus record option : " +
906
                                npr.record.which);
907
                        }
908
                    } else {
909
                        System.err.println("Might have a diagnostic here...");
910
                    }
911
                    // If not, it's probably a diagnostic....
912
                }
913
                // Let's hope we have managed to set cl in some of the above
914
            }
915
        }
916
    } 
917

    
918
/**
919
 * 
920
 * 
921
 */
922
    private void explainDatabaseInfo() throws SearchException, InvalidQueryException {        
923
        clearAllDatabases();
924
        addDatatabse("IR-Explain-1");
925
        dbinfo.clear();
926
        setRecordSyntax("explain");
927
        SearchResponse_type r = sendSearch(new com.k_int.IR.QueryModels.PrefixString(
928
                    "@attrset exp-1 @attr 1=1 databaseInfo"), "expdbinfo",
929
                "dbinfoset");
930
        if (r.searchStatus.booleanValue()) {
931
            // OK, Our search for database info in the explain database seems to have worked...
932
            // Figure out what useful info we can from the available categories
933
            if (r.resultCount.intValue() > 0) {
934
                if (r.numberOfRecordsReturned.intValue() > 0) {
935
                    // Even better, it looks like we have some piggyback records
936
                    if (r.records.which == Records_type.responserecords_CID) {
937
                        processDatabaseInfoRecords((Vector) (r.records.o));
938
                    }
939
                    // If not, it's probably a diagnostic....
940
                }
941
                // Use present to get the records (For now we will rely on number of databases
942
                // being less that ssub ).
943
            }
944
        }
945
    } 
946

    
947
/**
948
 * 
949
 * 
950
 * 
951
 * @param records 
952
 */
953
    private void processDatabaseInfoRecords(Vector records) {        
954
        for (int i = 0; i < records.size(); i++) {
955
            NamePlusRecord_type npr = (NamePlusRecord_type) records.get(i);
956
            if (npr.record.which == record_inline13_type.retrievalrecord_CID) {
957
                EXTERNAL_type et = (EXTERNAL_type) npr.record.o;
958
                Object o = et.encoding.o;
959
                if (o instanceof Explain_Record_type) {
960
                    DatabaseInfo_type di = (DatabaseInfo_type) (((Explain_Record_type) o).o);
961
                    dbinfo.put(di.name, di);
962
                    System.err.println("Aviailable database: " + di.name);
963
                }
964
            }
965
        }
966
    } 
967

    
968
/**
969
 * 
970
 * 
971
 * 
972
 * @return 
973
 */
974
    public Enumeration getDatabases() {        
975
        return dbinfo.elements();
976
    } 
977
 }