File Coverage

blib/lib/Biblio/ILL/ISO/Answer.pm
Criterion Covered Total %
statement 84 116 72.4
branch 24 68 35.2
condition 1 6 16.6
subroutine 16 18 88.8
pod 15 15 100.0
total 140 223 62.7


line stmt bran cond sub pod time code
1             package Biblio::ILL::ISO::Answer;
2              
3             =head1 NAME
4              
5             Biblio::ILL::ISO::Answer - Perl extension for handling ISO 10161 interlibrary loan ILL-Answer messages
6              
7             =cut
8              
9 2     2   4741 use Biblio::ILL::ISO::ISO;
  2         9  
  2         225  
10 2     2   19 use Carp;
  2         6  
  2         255  
11              
12             =head1 VERSION
13              
14             Version 0.01
15              
16             =cut
17              
18             our $VERSION = '0.01';
19             #---------------------------------------------------------------------------
20             # Mods
21             # 0.01 - 2003.07.26 - original version
22             #---------------------------------------------------------------------------
23              
24             =head1 DESCRIPTION
25              
26             Biblio::ILL::ISO::Answer is a derivation of the abstract
27             Biblio::ILL::ISO::ISO object, and handles the ILL-Answer message type.
28              
29             =head1 EXPORT
30              
31             None.
32              
33             =head1 ERROR HANDLING
34              
35             Each of the set_() methods will croak on missing or invalid parameters.
36              
37             =cut
38              
39 2     2   3724 BEGIN{@ISA = qw ( Biblio::ILL::ISO::ISO ); }
40              
41             =head1 FROM THE ASN DEFINITION
42            
43              
44             ILL-Answer ::= [APPLICATION 4] SEQUENCE {
45             protocol-version-num [0] IMPLICIT INTEGER, -- {
46             -- version-1 (1),
47             -- version-2 (2)
48             -- },
49             transaction-id [1] IMPLICIT Transaction-Id,
50             service-date-time [2] IMPLICIT Service-Date-Time,
51             requester-id [3] IMPLICIT System-Id OPTIONAL,
52             -- mandatory when using store-and-forward communications
53             -- optional when using connection-oriented communications
54             responder-id [4] IMPLICIT System-Id OPTIONAL,
55             -- mandatory when using store-and-forward communications
56             -- optional when using connection-oriented communications
57             transaction-results [31] IMPLICIT Transaction-Results,
58             results-explanation [32] Results-Explanation OPTIONAL,
59             -- dc hmm
60             -- optional if transaction-results equals RETRY, UNFILLED,
61             -- WILL-SUPPLY or HOLD-PLACED;
62             -- required if transaction-results equals CONDITIONAL,
63             -- LOCATIONS-PROVIDED or ESTIMATE
64             -- DC - 'EXTERNAL' is not supported in Convert::ASN1
65             -- responder-specific-results [33] EXTERNAL OPTIONAL,
66             -- this type is mandatory if results-explanation
67             -- chosen for any result
68             -- has the value "responder-specific".
69             -- DC - 'EXTERNAL' definition (see Supplemental-Item-Description)
70             -- supplemental-item-description [17] IMPLICIT Supplemental-Item-Description OPTIONAL,
71             send-to-list [23] IMPLICIT Send-To-List-Type OPTIONAL,
72             already-tried-list [34] IMPLICIT Already-Tried-List-Type OPTIONAL,
73             responder-optional-messages [28] IMPLICIT Responder-Optional-Messages-Type OPTIONAL,
74             responder-note [46] ILL-String OPTIONAL,
75             ill-answer-extensions [49] IMPLICIT SEQUENCE OF Extension OPTIONAL
76             }
77              
78             =cut
79              
80             =head1 CONSTRUCTORS
81              
82             new()
83              
84             Base constructor for the class. It just returns a completely
85             empty message object, which you'll need to populate with the
86             various set_() methods, or use the read() method to read an
87             Answer message from a file (followed by a call to
88             from_asn() to turn the read's returned hash into a proper
89             Answer message.
90              
91             The constructor also initializes the Convert::ASN1 if it
92             hasn't been initialized.
93              
94             =cut
95             #---------------------------------------------------------------
96             #
97             #---------------------------------------------------------------
98             sub new {
99 2     2 1 15 my $class = shift;
100 2         3 my $self = {};
101              
102 2 50       7 Biblio::ILL::ISO::ISO::_init() if (not $Biblio::ILL::ISO::ISO::_asn_initialized);
103 2         5 $self->{"ASN_TYPE"} = "ILL-Answer";
104              
105 2   33     10 bless($self, ref($class) || $class);
106 2         13 return ($self);
107             }
108              
109              
110             #---------------------------------------------------------------
111             #
112             #---------------------------------------------------------------
113             sub as_pretty_string {
114 0     0 1 0 my $self = shift;
115              
116 0         0 foreach my $key (sort keys %$self) {
117 0 0       0 if ($key ne "ASN_TYPE") {
118 0         0 print "\n[$key]\n";
119 0         0 print $self->{$key}->as_pretty_string();
120             }
121             }
122 0         0 return;
123             }
124              
125             #---------------------------------------------------------------
126             # This will return a structure usable by Convert::ASN1
127             #---------------------------------------------------------------
128             sub as_asn {
129 1     1 1 4 my $self = shift;
130              
131 1         4 my %h = ();
132 1         13 foreach my $key (sort keys %$self) {
133 12 100       27 if ($key ne "ASN_TYPE") {
134             #print "\n[$key]\n";
135 11         53 $h{$key} = $self->{$key}->as_asn();
136             }
137             }
138 1         5 return \%h;
139             }
140              
141             =head1 METHODS
142              
143             For any example code, assume the following:
144             my $msg = new Biblio::ILL::ISO::Answer;
145              
146             =cut
147              
148             #---------------------------------------------------------------
149             #
150             #---------------------------------------------------------------
151             =head1
152              
153             =head2 from_asn($href)
154              
155             To read a message from a file, use the following:
156              
157             my $href = $msg->read("msg_04.answer.ber");
158             $msg = $msg->from_asn($href);
159              
160             The from_asn() method turns the hash returned from read() into
161             a proper message-type object.
162              
163             =cut
164             sub from_asn {
165 0     0 1 0 my $self = shift;
166 0         0 my $href = shift;
167              
168 0         0 foreach my $k (keys %$href) {
169              
170 0 0 0     0 if ($k =~ /^protocol-version-num$/) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
171 0         0 $self->{$k} = new Biblio::ILL::ISO::ProtocolVersionNum();
172 0         0 $self->{$k}->from_asn($href->{$k});
173              
174             } elsif ($k =~ /^transaction-id$/) {
175 0         0 $self->{$k} = new Biblio::ILL::ISO::TransactionId();
176 0         0 $self->{$k}->from_asn($href->{$k});
177              
178             } elsif ($k =~ /^service-date-time$/) {
179 0         0 $self->{$k} = new Biblio::ILL::ISO::ServiceDateTime();
180 0         0 $self->{$k}->from_asn($href->{$k});
181              
182             } elsif (($k =~ /^requester-id$/)
183             || ($k =~ /^responder-id$/)
184             ) {
185 0         0 $self->{$k} = new Biblio::ILL::ISO::SystemId();
186 0         0 $self->{$k}->from_asn($href->{$k});
187              
188             } elsif ($k =~ /^transaction-results$/) {
189 0         0 $self->{$k} = new Biblio::ILL::ISO::TransactionResults();
190 0         0 $self->{$k}->from_asn($href->{$k});
191              
192             } elsif ($k =~ /^results-explanation$/) {
193 0         0 $self->{$k} = new Biblio::ILL::ISO::ResultsExplanation();
194 0         0 $self->{$k}->from_asn($href->{$k});
195              
196             # This is EXTERNAL, which we don't handle.
197             #} elsif ($k =~ /^supplemental-item-description$/) {
198             # $self->{$k} = new Biblio::ILL::ISO::SupplementalItemDescription();
199             # $self->{$k}->from_asn($href->{$k});
200              
201             } elsif ($k =~ /^send-to-list$/) {
202 0         0 $self->{$k} = new Biblio::ILL::ISO::SendToListType();
203 0         0 $self->{$k}->from_asn($href->{$k});
204              
205             } elsif ($k =~ /^already-tried-list$/) {
206 0         0 $self->{$k} = new Biblio::ILL::ISO::AlreadyTriedListType();
207 0         0 $self->{$k}->from_asn($href->{$k});
208              
209             } elsif ($k =~ /^responder-optional-messages$/) {
210 0         0 $self->{$k} = new Biblio::ILL::ISO::ResponderOptionalMessageType();
211 0         0 $self->{$k}->from_asn($href->{$k});
212              
213             } elsif ($k =~ /^responder-note$/) {
214 0         0 $self->{$k} = new Biblio::ILL::ISO::ILLString();
215 0         0 $self->{$k}->from_asn($href->{$k});
216              
217             } else {
218 0         0 croak "invalid " . ref($self) . " element: [$k]";
219             }
220              
221             }
222 0         0 return $self;
223             }
224              
225             #---------------------------------------------------------------
226             #
227             #---------------------------------------------------------------
228             =head1
229              
230             =head2 set_protocol_version_num($pvn)
231              
232             Sets the protocol version number.
233             Acceptable parameter values are the strings:
234             version-1
235             version-2
236              
237             =cut
238             sub set_protocol_version_num {
239 1     1 1 5 my $self = shift;
240 1         9 my ($parm) = shift;
241              
242 1 50       8 croak "missing protocol-version-num" unless $parm;
243              
244 1         5 $self->{"protocol-version-num"} = new Biblio::ILL::ISO::ProtocolVersionNum($parm);
245              
246 1         2 return;
247             }
248              
249             #---------------------------------------------------------------
250             #
251             #---------------------------------------------------------------
252             =head1
253              
254             =head2 set_transaction_id($tid)
255              
256             Sets the message's transaction-id.
257             Expects a valid Biblio::ILL::ISO::TransactionId.
258              
259             my $tid = new Biblio::ILL::ISO::TransactionId("PLS","001","",
260             new Biblio::ILL::ISO::SystemId("MWPL"));
261             $msg->set_transaction_id($tid);
262              
263             This is a mandatory field.
264              
265             =cut
266             sub set_transaction_id {
267 1     1 1 5 my $self = shift;
268 1         1 my ($parm) = shift;
269              
270 1 50       3 croak "missing transaction-id" unless $parm;
271 1 50       4 croak "invalid transaction-id" unless (ref($parm) eq "Biblio::ILL::ISO::TransactionId");
272              
273 1         2 $self->{"transaction-id"} = $parm;
274              
275 1         3 return;
276             }
277              
278             #---------------------------------------------------------------
279             #
280             #---------------------------------------------------------------
281             =head1
282              
283             =head2 set_service_date_time($sdt)
284              
285             Sets the message's service-date-time.
286             Expects a valid Biblio::ILL::ISO::ServiceDateTime.
287              
288             my $dt_this = new Biblio::ILL::ISO::DateTime("20030623","114400");
289             my $dt_orig = new Biblio::ILL::ISO::DateTime("20030623","114015")
290             my $sdt = new Biblio::ILL::ISO::ServiceDateTime( $dt_this, $dt_orig);
291             $msg->set_service_date_time($sdt);
292              
293             This is a mandatory field.
294              
295             =cut
296             sub set_service_date_time {
297 1     1 1 3 my $self = shift;
298 1         4 my ($sdt) = shift;
299              
300 1 50       4 croak "missing service-date-time" unless $sdt;
301 1 50       4 croak "invalid service-date-time" unless (ref($sdt) eq "Biblio::ILL::ISO::ServiceDateTime");
302              
303 1         2 $self->{"service-date-time"} = $sdt;
304              
305 1         3 return;
306             }
307              
308             #---------------------------------------------------------------
309             #
310             #---------------------------------------------------------------
311             =head1
312              
313             =head2 set_requester_id($reqid)
314              
315             Sets the message's requester-id.
316             Expects a valid Biblio::ILL::ISO::SystemId.
317              
318             my $reqid = new Biblio::ILL::ISO::SystemId();
319             $reqid->set_person_name("David A. Christensen");
320             $msg->set_requester_id($reqid);
321              
322             This is an optional field.
323              
324             =cut
325             sub set_requester_id {
326 1     1 1 5 my $self = shift;
327 1         1 my ($parm) = shift;
328              
329 1 50       4 croak "missing requester-id" unless $parm;
330 1 50       3 croak "invalid requester-id" unless (ref($parm) eq "Biblio::ILL::ISO::SystemId");
331              
332 1         2 $self->{"requester-id"} = $parm;
333              
334 1         3 return;
335             }
336              
337             #---------------------------------------------------------------
338             #
339             #---------------------------------------------------------------
340             =head1
341              
342             =head2 set_responder_id($resid)
343              
344             Sets the message's responder-id.
345             Expects a valid Biblio::ILL::ISO::SystemId.
346              
347             my $resid = new Biblio::ILL::ISO::SystemId("MWPL");
348             $msg->set_responder_id($resid);
349              
350             This is an optional field.
351              
352             =cut
353             sub set_responder_id {
354 1     1 1 4 my $self = shift;
355 1         2 my ($parm) = shift;
356              
357 1 50       2 croak "missing responder-id" unless $parm;
358 1 50       4 croak "invalid responder-id" unless (ref($parm) eq "Biblio::ILL::ISO::SystemId");
359              
360 1         3 $self->{"responder-id"} = $parm;
361              
362 1         3 return;
363             }
364              
365             #---------------------------------------------------------------
366             #
367             #---------------------------------------------------------------
368             =head1
369              
370             =head2 set_transaction_results($tr)
371              
372             Sets the message's transaction-results.
373             Expects a valid Biblio::ILL::ISO::TransactionResults.
374              
375             my $tr = new Biblio::ILL::ISO::TransactionResults("conditional");
376             $msg->set_transaction_results($tr);
377              
378             This is a mandatory field.
379              
380             =cut
381             sub set_transaction_results {
382 1     1 1 6 my $self = shift;
383 1         2 my ($parm) = shift;
384              
385 1 50       10 $parm = new Biblio::ILL::ISO::TransactionResults("unfilled") unless ($parm);
386              
387 1 50       4 croak "invalid transaction-results" unless (ref($parm) eq "Biblio::ILL::ISO::TransactionResults");
388              
389 1         3 $self->{"transaction-results"} = $parm;
390              
391 1         2 return;
392             }
393              
394             #---------------------------------------------------------------
395             #
396             #---------------------------------------------------------------
397             =head1
398              
399             =head2 set_results_explanation($rexp)
400              
401             Sets the message's results-explanation.
402             Expects a valid Biblio::ILL::ISO::ResultsExplanation.
403              
404             # Build a location sequence
405             my $sid = new Biblio::ILL::ISO::SystemId();
406             $sid->set_person_name("David A. Christensen");
407             $sid->set_institution_symbol("MWPL");
408             my $sa = new Biblio::ILL::ISO::SystemAddress("SMTP","pls\@gov.mb.ca");
409             my $note = new Biblio::ILL::ISO::ILLString("This is a location note.");
410             my $loc = new Biblio::ILL::ISO::LocationInfo($sid,
411             $sa,
412             $note,
413             );
414             my $locseq = new Biblio::ILL::ISO::LocationInfoSequence( $loc );
415             $sid = new Biblio::ILL::ISO::SystemId();
416             $sid->set_institution_name("Brandon Public Library");
417             $sa = new Biblio::ILL::ISO::SystemAddress("SMTP","library\@brandon.mb.ca");
418             $loc = new Biblio::ILL::ISO::LocationInfo($sid, $sa);
419             $locseq->add($loc);
420              
421             # Build a conditional-results condition
422             my $condition = new Biblio::ILL::ISO::ConditionalResultsCondition("charges");
423             my $dt = new Biblio::ILL::ISO::ISODate("20030727");
424             my $tm = new Biblio::ILL::ISO::TransportationMode("Canada Post");
425             my $ds = new Biblio::ILL::ISO::DeliveryService( $tm )
426             my $conres = new Biblio::ILL::ISO::ConditionalResults($condition,
427             $dt,
428             $locseq,
429             $ds
430             );
431              
432             my $rexp = new Biblio::ILL::ISO::ResultsExplanation( $conres );
433             $msg->set_results_explanation($rexp);
434              
435             This is an optional field.
436              
437             =cut
438             sub set_results_explanation {
439 1     1 1 6 my $self = shift;
440 1         2 my ($parm) = shift;
441              
442 1 50       13 croak "missing results-explanation" unless $parm;
443 1 50       4 croak "invalid results-explanation" unless (ref($parm) eq "Biblio::ILL::ISO::ResultsExplanation");
444              
445 1         2 $self->{"results-explanation"} = $parm;
446              
447 1         3 return;
448             }
449              
450             #---------------------------------------------------------------
451             # This is EXTERNAL, which we don't handle
452             #---------------------------------------------------------------
453             #sub set_supplemental_item_description {
454             # my $self = shift;
455             # my ($parm) = shift;
456             #
457             # croak "missing supplemental-item-description" unless $parm;
458             # croak "invalid supplemental-item-description" unless (ref($parm) eq "Biblio::ILL::ISO::SupplementalItemDescription");
459             #
460             # $self->{"supplemental-item-description"} = $parm;
461             #
462             # return;
463             #}
464              
465             #---------------------------------------------------------------
466             #
467             #---------------------------------------------------------------
468             =head1
469              
470             =head2 set_send_to_list($stlts)
471              
472             Sets the message's send-to-list.
473             Expects a valid Biblio::ILL::ISO::SendToListTypeSequence.
474              
475             my $sid = new Biblio::ILL::ISO::SystemId("MBOM");
476             my $stlt = new Biblio::ILL::ISO::SendToListType( $sid );
477             my $stlts = new Biblio::ILL::ISO::SendToListTypeSequence( $stlt );
478              
479             $sid = new Biblio::ILL::ISO::SystemId("MWPL");
480             my $act = new Biblio::ILL::ISO::AccountNumber("PLS001");
481             my $sa = new Biblio::ILL::ISO::SystemAddress("SMTP","pls\@gov.mb.ca");
482             $stlts->add( new Biblio::ILL::ISO::SendToListType( $sid,
483             $act,
484             $sa
485             )
486             );
487              
488             $msg->set_send_to_list($stlts);
489              
490             This is an optional field.
491              
492             =cut
493             sub set_send_to_list {
494 1     1 1 5 my $self = shift;
495 1         2 my ($parm) = shift;
496              
497 1 50       3 croak "missing send-to-list" unless $parm;
498 1 50       8 croak "invalid send-to-list" unless (ref($parm) eq "Biblio::ILL::ISO::SendToListTypeSequence");
499              
500 1         4 $self->{"send-to-list"} = $parm;
501              
502 1         2 return;
503             }
504              
505             #---------------------------------------------------------------
506             #
507             #---------------------------------------------------------------
508             =head1
509              
510             =head2 set_already_tried_list($atlt)
511              
512             Sets the message's already-tried-list.
513             Expects a valid Biblio::ILL::ISO::AlreadyTriedListType.
514              
515             my $sid = new Biblio::ILL::ISO::SystemId("BVAS");
516             my $atlt = new Biblio::ILL::ISO::AlreadyTriedListType( $sid );
517              
518             $sid = new Biblio::ILL::ISO::SystemId();
519             $sid->set_institution_name("Winnipeg Public Library");
520             $atlt->add($sid);
521              
522             $sid = new Biblio::ILL::ISO::SystemId();
523             $sid->set_person_name("Frank Emil Urwald");
524             $atlt->add($sid);
525              
526             $atlt->add( new Biblio::ILL::ISO::SystemId("MBOM"));
527              
528             $msg->set_already_tried_list($atlt);
529              
530             This is an optional field.
531              
532             =cut
533             sub set_already_tried_list {
534 1     1 1 4 my $self = shift;
535 1         2 my ($parm) = shift;
536              
537 1 50       2 croak "missing already-tried-list" unless $parm;
538 1 50       4 croak "invalid already-tried-list" unless (ref($parm) eq "Biblio::ILL::ISO::AlreadyTriedListType");
539              
540 1         2 $self->{"already-tried-list"} = $parm;
541              
542 1         2 return;
543             }
544              
545             #---------------------------------------------------------------
546             #
547             #---------------------------------------------------------------
548             =head1
549              
550             =head2 set_responder_optional_messages($rom)
551              
552             Sets the message's responder-optional-messages.
553             Expects a valid Biblio::ILL::ISO::ResponderOptionalMessageType.
554              
555             my $rom = new Biblio::ILL::ISO::ResponderOptionalMessageType(1,1,
556             "desires",
557             "requires"
558             );
559             $msg->set_responder_optional_messages($rom);
560              
561             This is an optional field.
562              
563             =cut
564             sub set_responder_optional_messages {
565 1     1 1 4 my $self = shift;
566 1         2 my ($parm) = shift;
567              
568 1 50       12 croak "missing responder-optional-messages" unless $parm;
569 1 50       4 croak "invalid responder-optional-messages" unless (ref($parm) eq "Biblio::ILL::ISO::ResponderOptionalMessageType");
570              
571 1         3 $self->{"responder-optional-messages"} = $parm;
572              
573 1         1 return;
574             }
575              
576             #---------------------------------------------------------------
577             #
578             #---------------------------------------------------------------
579             =head1
580              
581             =head2 set_responder_note($note)
582              
583             Sets the message's responder-note.
584             Expects a simple text string.
585              
586             $msg->set_responder_note("This is a responder note");
587              
588             This is an optional field.
589              
590             =cut
591             sub set_responder_note {
592 1     1 1 4 my $self = shift;
593 1         2 my ($parm) = shift;
594              
595 1 50       3 croak "missing responder-note" unless $parm;
596 1 50       3 croak "invalid responder-note" unless (ref($parm) eq "Biblio::ILL::ISO::ILLString");
597              
598 1         2 $self->{"responder-note"} = $parm;
599              
600 1         2 return;
601             }
602              
603             =head1 RELATED MODULES
604              
605             Biblio::ILL::ISO::ISO
606             Biblio::ILL::ISO::Request
607             Biblio::ILL::ISO::ForwardNotification
608             Biblio::ILL::ISO::Shipped
609             Biblio::ILL::ISO::Answer
610             Biblio::ILL::ISO::ConditionalReply
611             Biblio::ILL::ISO::Cancel
612             Biblio::ILL::ISO::CancelReply
613             Biblio::ILL::ISO::Received
614             Biblio::ILL::ISO::Recall
615             Biblio::ILL::ISO::Returned
616             Biblio::ILL::ISO::CheckedIn
617             Biblio::ILL::ISO::Overdue
618             Biblio::ILL::ISO::Renew
619             Biblio::ILL::ISO::RenewAnswer
620             Biblio::ILL::ISO::Lost
621             Biblio::ILL::ISO::Damaged
622             Biblio::ILL::ISO::Message
623             Biblio::ILL::ISO::StatusQuery
624             Biblio::ILL::ISO::StatusOrErrorReport
625             Biblio::ILL::ISO::Expired
626              
627             =cut
628              
629             =head1 SEE ALSO
630              
631             See the README for system design notes.
632              
633             For more information on Interlibrary Loan standards (ISO 10160/10161),
634             a good place to start is:
635              
636             http://www.nlc-bnc.ca/iso/ill/main.htm
637              
638             =cut
639              
640             =head1 AUTHOR
641              
642             David Christensen,
643              
644             =cut
645              
646              
647             =head1 COPYRIGHT AND LICENSE
648              
649             Copyright 2003 by David Christensen
650              
651             This library is free software; you can redistribute it and/or modify it
652             under the same terms as Perl itself.
653              
654             =cut
655              
656             1;