]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Utils/MFHDParser.pm
Whitespace patch to bring MFHD code into line with new perltidy standard
[working/Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Utils / MFHDParser.pm
1 package OpenILS::Utils::MFHDParser;
2 use strict;
3 use warnings;
4
5 use OpenSRF::EX qw/:try/;
6 use Time::HiRes qw(time);
7 use OpenILS::Utils::Fieldmapper;
8 use OpenSRF::Utils::SettingsClient;
9 use OpenSRF::Utils::Logger qw/$logger/;
10
11 use OpenILS::Utils::MFHD;
12 use MARC::File::XML (BinaryEncoding => 'utf8');
13 use Data::Dumper;
14
15 sub new { return bless({}, shift()); }
16
17 =head1 Subroutines
18
19 =over
20
21 =item * format_textual_holdings($field)
22
23 =back
24
25 Returns concatenated subfields $a with $z for textual holdings (866-868)
26
27 =cut
28
29 sub format_textual_holdings {
30     my ($self, $field) = @_;
31     my $holdings;
32     my $public_note;
33
34     $holdings = $field->subfield('a');
35     if (!$holdings) {
36         return undef;
37     }
38
39     $public_note = $field->subfield('z');
40     if ($public_note) {
41         return "$holdings - $public_note";
42     }
43     return $holdings;
44 }
45
46 =over
47
48 =item * mfhd_to_hash($mfhd_xml)
49
50 =back
51
52 Returns a Perl hash containing fields of interest from the MFHD record
53
54 =cut
55
56 sub mfhd_to_hash {
57     my ($self, $mfhd_xml) = @_;
58
59     my $marc;
60     my $mfhd;
61
62     my $location            = '';
63     my $holdings            = [];
64     my $supplements         = [];
65     my $indexes             = [];
66     my $current_holdings    = [];
67     my $current_supplements = [];
68     my $current_indexes     = [];
69     my $online              = [];    # Laurentian extension to MFHD standard
70     my $missing             = [];    # Laurentian extension to MFHD standard
71     my $incomplete          = [];    # Laurentian extension to MFHD standard
72
73     try {
74         $marc = MARC::Record->new_from_xml($mfhd_xml);
75     }
76     otherwise {
77         $logger->error("Failed to convert MFHD XML to MARC: " . shift());
78         $logger->error("Failed MFHD XML: $mfhd_xml");
79     };
80
81     if (!$marc) {
82         return undef;
83     }
84
85     try {
86         $mfhd = MFHD->new($marc);
87     }
88     otherwise {
89         $logger->error("Failed to parse MFHD: " . shift());
90         $logger->error("Failed MFHD XML: $mfhd_xml");
91     };
92
93     if (!$mfhd) {
94         return undef;
95     }
96
97     try {
98         foreach my $field ($marc->field('852')) {
99             foreach my $subfield_ref ($field->subfields) {
100                 my ($subfield, $data) = @$subfield_ref;
101                 $location .= $data . " -- ";
102             }
103         }
104     }
105     otherwise {
106         $logger->error("MFHD location parsing error: " . shift());
107     };
108
109     $location =~ s/ -- $//;
110
111     try {
112         foreach my $field ($marc->field('866')) {
113             my $textual_holdings = $self->format_textual_holdings($field);
114             if ($textual_holdings) {
115                 push @$holdings, $textual_holdings;
116             }
117         }
118         foreach my $field ($marc->field('867')) {
119             my $textual_holdings = $self->format_textual_holdings($field);
120             if ($textual_holdings) {
121                 push @$supplements, $textual_holdings;
122             }
123         }
124         foreach my $field ($marc->field('868')) {
125             my $textual_holdings = $self->format_textual_holdings($field);
126             if ($textual_holdings) {
127                 push @$indexes, $textual_holdings;
128             }
129         }
130
131         foreach my $cap_id ($mfhd->captions('853')) {
132             my @curr_holdings = $mfhd->holdings('863', $cap_id);
133             next unless scalar @curr_holdings;
134             foreach (@curr_holdings) {
135                 push @$current_holdings, $_->format();
136             }
137         }
138
139         foreach my $cap_id ($mfhd->captions('854')) {
140             my @curr_supplements = $mfhd->holdings('864', $cap_id);
141             next unless scalar @curr_supplements;
142             foreach (@curr_supplements) {
143                 push @$current_supplements, $_->format();
144             }
145         }
146
147         foreach my $cap_id ($mfhd->captions('855')) {
148             my @curr_indexes = $mfhd->holdings('865', $cap_id);
149             next unless scalar @curr_indexes;
150             foreach (@curr_indexes) {
151                 push @$current_indexes, $_->format();
152             }
153         }
154
155         # Laurentian extensions
156         foreach my $field ($marc->field('530')) {
157             my $online_stmt = $self->format_textual_holdings($field);
158             if ($online_stmt) {
159                 push @$online, $online_stmt;
160             }
161         }
162
163         foreach my $field ($marc->field('590')) {
164             my $missing_stmt = $self->format_textual_holdings($field);
165             if ($missing_stmt) {
166                 push @$missing, $missing_stmt;
167             }
168         }
169
170         foreach my $field ($marc->field('591')) {
171             my $incomplete_stmt = $self->format_textual_holdings($field);
172             if ($incomplete_stmt) {
173                 push @$incomplete, $incomplete_stmt;
174             }
175         }
176     }
177     otherwise {
178         $logger->error("MFHD statement parsing error: " . shift());
179     };
180
181     return {
182         location            => $location,
183         holdings            => $holdings,
184         current_holdings    => $current_holdings,
185         supplements         => $supplements,
186         current_supplements => $current_supplements,
187         indexes             => $indexes,
188         current_indexes     => $current_indexes,
189         missing             => $missing,
190         incomplete          => $incomplete,
191     };
192 }
193
194 =over
195
196 =item * init_holdings_virtual_record()
197
198 =back
199
200 Initialize the serial virtual record (svr) instance
201
202 =cut
203
204 sub init_holdings_virtual_record {
205     my $record = Fieldmapper::serial::virtual_record->new;
206     $record->id();
207     $record->location();
208     $record->owning_lib();
209     $record->holdings([]);
210     $record->current_holdings([]);
211     $record->supplements([]);
212     $record->current_supplements([]);
213     $record->indexes([]);
214     $record->current_indexes([]);
215     $record->online([]);
216     $record->missing([]);
217     $record->incomplete([]);
218     return $record;
219 }
220
221 =over
222
223 =item * init_holdings_virtual_record($mfhd)
224
225 =back
226
227 Given an MFHD record, return a populated svr instance
228
229 =cut
230
231 sub generate_svr {
232     my ($self, $id, $mfhd, $owning_lib) = @_;
233
234     if (!$mfhd) {
235         return undef;
236     }
237
238     my $record   = init_holdings_virtual_record();
239     my $holdings = $self->mfhd_to_hash($mfhd);
240
241     $record->id($id);
242     $record->owning_lib($owning_lib);
243
244     if (!$holdings) {
245         return $record;
246     }
247
248     $record->location($holdings->{location});
249     $record->holdings($holdings->{holdings});
250     $record->current_holdings($holdings->{current_holdings});
251     $record->supplements($holdings->{supplements});
252     $record->current_supplements($holdings->{current_supplements});
253     $record->indexes($holdings->{indexes});
254     $record->current_indexes($holdings->{current_indexes});
255     $record->online($holdings->{online});
256     $record->missing($holdings->{missing});
257     $record->incomplete($holdings->{incomplete});
258
259     return $record;
260 }
261
262 1;
263
264 # vim: ts=4:sw=4:noet