File Coverage

blib/lib/Net/OAI/Record/Header.pm
Criterion Covered Total %
statement 73 84 86.9
branch 43 54 79.6
condition 8 18 44.4
subroutine 13 15 86.6
pod 11 11 100.0
total 148 182 81.3


line stmt bran cond sub pod time code
1             package Net::OAI::Record::Header;
2              
3 17     17   86 use strict;
  17         35  
  17         426  
4 17     17   85 use warnings;
  17         30  
  17         483  
5 17     17   87 use base qw( XML::SAX::Base );
  17         29  
  17         1203  
6 17     17   87 use Carp qw( carp );
  17         33  
  17         19304  
7             our $VERSION = "1.16_12";
8              
9              
10             =head1 NAME
11              
12             Net::OAI::Record::Header - class for record header representation
13              
14             =head1 SYNOPSIS
15              
16             =head1 DESCRIPTION
17              
18             Actually this class implements a SAX filter for the
19             complete C OAI-PMH element. The contents of the C
20             child are collected into a header object and can be accessed by the
21             methods documented here.
22              
23             Events will be traditionally forwarded only from the subelement(s) of
24             the C child which makes it difficult to access data
25             contained in the (possibly multiple) C containers which may follow
26             the C in the C.
27              
28             Beginning from OAI-Harvester v1.20 a new "recordHandler" argument
29             may be given to the harvester functions C and C:
30             In contrast to a "metadataHandler" argument this will pass the "fwdAll"
31             argument to the constructor of this Header class and result in
32             forwarding all events in the C (including C itself) to
33             the handler specified, not only those from C children.
34              
35             In case of compatibility issues of Filters written for older veresions
36             you might set C<$Net::OAI::Harvester::OLDmetadataHandler = 1>,
37             in which case the metadataHandler Option behaves like a recordHandler.
38              
39             The SAX filter implemented by this class purposefully does not generate
40             any start_document() or end_document() events.
41             Consider inserting L as an additional
42             filtering stage if your handler(s) need these events, if they fail
43             class verification, or if you need a hook for capturing their result.
44              
45              
46             =head1 METHODS
47              
48             =head2 new()
49              
50             =cut
51              
52             sub new {
53 6410     6410 1 35281 my ( $class, %opts ) = @_;
54 6410   33     28930 my $self = bless \%opts, ref( $class ) || $class;
55 6410         19285 $self->{ status } = $self->{ identifier } = $self->{ datestamp } = '';
56 6410         12081 $self->{ _tagStack } = [];
57 6410         11267 $self->{ sets } = [];
58 6410         19158 $self->{ _insideHeader } = $self->{ _insideMetadata } = $self->{ _insideAbout } = 0;
59 6410         22214 return( $self );
60             }
61              
62             =head2 status()
63              
64             Gets the optional C attribute of the OAI header and returns either "deleted" or "".
65              
66             =cut
67              
68             sub status {
69 3     3 1 338 my ( $self, $status ) = @_;
70 3 100       9 if ( $status ) { $self->{ headerStatus } = $status; }
  1         3  
71 3         10 return( $self->{ headerStatus } );
72             }
73              
74             =head2 identifier()
75              
76             =cut
77              
78             sub identifier {
79 5007     5007 1 1088715 my ( $self, $id ) = @_;
80 5007 100       12356 if ( $id ) { $self->{ identifier } = $id; }
  1         3  
81 5007         18409 return( $self->{ identifier } );
82             }
83              
84             =head2 datestamp()
85              
86             =cut
87              
88             sub datestamp {
89 2     2 1 5 my ( $self, $datestamp ) = @_;
90 2 100       6 if ( $datestamp ) { $self->{ datestamp } = $datestamp; }
  1         3  
91 2         6 return( $self->{ datestamp } );
92             }
93              
94             =head2 setSpecs()
95              
96             =head2 sets() DEPRECATED
97              
98             =cut
99              
100             sub setSpecs {
101 1002     1002 1 1817 my ( $self, @sets ) = @_;
102 1002 100       2604 if ( @sets ) { $self->{ sets } = \@sets; }
  1         4  
103 1002         1297 return( @{ $self->{ sets } } );
  1002         3891  
104             }
105              
106             sub sets {
107 0     0 1 0 return setSpecs(@_);
108             }
109              
110             ## SAX Handlers
111              
112             sub start_prefix_mapping {
113 7042     7042 1 64806 my ($self, $mapping) = @_;
114 7042 50       17440 if ( $self->get_handler() ) {
115 7042         59996 return $self->SUPER::start_prefix_mapping( $mapping )};
116 0         0 die "HEADER: would have to buffer @{[$mapping]}";
  0         0  
117             }
118              
119             sub start_element {
120 64956     64956 1 467910 my ( $self, $element ) = @_;
121 64956 100       156559 unless ( $element->{ NamespaceURI } eq Net::OAI::Harvester::XMLNS_OAI ) {
122 32952 50 66     161302 $self->SUPER::start_element($element) if $self->{ fwdAll } or $self->{ _insideMetadata };
123 32952         773204 return;
124             }
125              
126 32004         46269 my $tagName = $element->{ LocalName };
127 32004         37948 push( @{$self->{ _tagStack }}, $tagName );
  32004         73360  
128 32004 100       112116 if ( $tagName eq 'record' ) {
    100          
    100          
    50          
    0          
129 1409         3309 $self->{ _insideHeader } = $self->{ _insideMetadata } = $self->{ _insideAbout } = 0}
130             elsif ( $tagName eq 'header' ) {
131 6409         10320 $self->{ _insideHeader } = 1;
132             $self->{ headerStatus } = ( exists $element->{ Attributes }{ '{}status' } )
133             ? $element->{ Attributes }{ '{}status' }{ Value }
134 6409 100       17920 : "";
135             }
136             elsif ( $self->{ _insideHeader } ) {
137             }
138             elsif ( $tagName eq 'metadata' ) {
139 1408         2496 $self->{ _insideMetadata } = 1;
140             }
141             elsif ( $tagName eq 'about' ) {
142 0         0 $self->{ _insideAbout } = 1;
143             }
144             else {
145 0         0 carp "who am I? ($tagName)";
146 0         0 return $self->SUPER::start_element($element);
147             };
148 32004 100       177043 return $self->SUPER::start_element($element) if $self->{ fwdAll };
149             }
150              
151             sub end_element {
152 64956     64956 1 462672 my ( $self, $element ) = @_;
153 64956 100       156643 unless ( $element->{ NamespaceURI } eq Net::OAI::Harvester::XMLNS_OAI ) {
154 32952 50 66     154886 $self->SUPER::end_element($element) if $self->{ fwdAll } or $self->{ _insideMetadata };
155 32952         198681 return;
156             }
157              
158 32004         37499 pop( @{$self->{ _tagStack }} );
  32004         65054  
159 32004         56304 my $tagName = $element->{ LocalName };
160 32004 100       98946 if ( $tagName eq 'header' ) {
    100          
    100          
    100          
    50          
    50          
161 6409         9876 $self->{ _insideHeader } = 0;
162 6409 50 33     43841 (defined $self->{header}) && ($self->{header} =~ /\S/) && carp "Excess content in record header: ".$self->{ header };
163             }
164             elsif ( $tagName eq 'setSpec' ) {
165 9960         12119 push( @{ $self->{ sets } }, $self->{ setSpec } );
  9960         26757  
166             }
167             elsif ( $self->{ _insideHeader } ) {
168             }
169             elsif ( $tagName eq 'metadata' ) {
170 1408         2956 $self->{ _insideMetadata } = 0;
171             }
172             elsif ( $tagName eq 'about' ) {
173 0         0 $self->{ _insideAbout } = 0;
174             }
175             elsif ( $tagName eq 'record' ) {
176 1409         2716 delete $self->{ _insideHeader };
177 1409         2316 delete $self->{ _insideMetadata };
178 1409         2471 delete $self->{ _insideAbout };
179 1409         2810 delete $self->{ _tagStack };
180             }
181             else {
182 0         0 carp "who am I? ($tagName)";
183 0         0 return $self->SUPER::end_element( $element );
184             };
185 32004 100       129653 return $self->SUPER::end_element($element) if $self->{ fwdAll };
186             }
187              
188              
189             sub ignorable_whitespace {
190 0     0 1 0 my ( $self, $characters ) = @_;
191 0 0 0     0 return $self->SUPER::ignorable_whitespace( $characters ) if $self->{ fwdAll } or $self->{ _insideMetadata };
192             }
193              
194             sub characters {
195 130762     130762 1 1291958 my ( $self, $characters ) = @_;
196 130762 100       413432 $self->{ $self->{ _tagStack }[-1] } .= $characters->{ Data } if $self->{ _insideHeader };
197 130762 100 66     712970 return $self->SUPER::characters( $characters ) if $self->{ fwdAll } or $self->{ _insideMetadata };
198             }
199              
200             1;
201