1 package OpenILS::Application::Cat::Utils;
2 use strict; use warnings;
3 use OpenILS::Application::AppUtils;
4 use OpenILS::Utils::Fieldmapper;
7 use OpenSRF::Utils::SettingsParser;
8 use OpenILS::Utils::FlatXML;
9 use OpenILS::Application::WORM;
11 my $utils = OpenILS::Application::Cat::Utils->new();
13 my $parser = XML::LibXML->new();
14 my $xslt = XML::LibXSLT->new();
15 my $xslt_doc = $parser->parse_file( "/pines/cvs/ILS/Open-ILS/xsl/MARC21slim2MODS.xsl" );
16 my $mods_sheet = $xslt->parse_stylesheet( $xslt_doc );
18 my $isbn_xpath = "//mods:mods/mods:identifier[\@type='isbn']";
19 my $resource_xpath = "//mods:mods/mods:typeOfResource";
24 $class = ref($class) || $class;
25 return bless( {}, $class );
29 # ---------------------------------------------------------------------------
30 # Converts an XML nodeset into a tree
31 # This method expects a blessed Fieldmapper::biblio::record_node object
33 my($class, $nodeset) = @_;
35 for my $child (@$nodeset) {
36 next unless ($child and defined($child->parent_node));
37 my $parent = $nodeset->[$child->parent_node];
39 warn "No Parent For " . $child->intra_doc_id() . "\n";
41 $parent->children([]) unless defined($parent->children);
44 push( @{$parent->children}, $child );
51 # ---------------------------------------------------------------------------
52 # Converts a tree into an xml nodeset
53 # This method expects a blessed Fieldmapper::biblio::record_node object
56 my($self, $node, $newnodes) = @_;
58 return $newnodes unless $node;
60 if(!$newnodes) { $newnodes = []; }
62 push( @$newnodes, $node );
64 if( $node->children() ) {
66 for my $child (@{ $node->children() }) {
68 new Fieldmapper::biblio::record_node ($child);
70 if(!defined($child->parent_node)) {
71 $child->parent_node($node->intra_doc_id); $child->ischanged(1); #just to be sure
74 $self->tree2nodeset( $child, $newnodes );
78 $node->children([]); #we don't need them hanging around
83 # Removes any deleted nodes from the tree
86 my($self, $nodeset) = @_;
88 for my $node (@$nodeset) {
89 if(!$node->isdeleted() ) {
90 push @newnodes, $node;
100 # ---------------------------------------------------------------------------
101 # Grabs the data 'we want' from the MODS doc and returns it in hash form
102 # ---------------------------------------------------------------------------
103 sub mods_values_to_mods_slim {
104 my( $self, $modsperl ) = @_;
110 my $tmp = $modsperl->{title};
112 if(!$tmp) { $title = ""; }
114 ($title = $tmp->{proper}) ||
115 ($title = $tmp->{translated}) ||
116 ($title = $tmp->{abbreviated}) ||
117 ($title = $tmp->{uniform});
120 $tmp = $modsperl->{author};
121 if(!$tmp) { $author = ""; }
123 ($author = $tmp->{personal}) ||
124 ($author = $tmp->{other}) ||
125 ($author = $tmp->{corporate}) ||
126 ($author = $tmp->{conference});
129 $tmp = $modsperl->{subject};
130 if(!$tmp) { $subject = []; }
132 for my $key( keys %{$tmp}) {
133 push(@$subject, $tmp->{$key}) if $tmp->{$key};
137 return { title => $title, author => $author, subject => $subject };
141 sub _marcxml_to_perl {
142 my($self, $marcxml) = @_;
143 my $xmldoc = $parser->parse_string( $marcxml );
144 my $mods = $mods_sheet->transform($xmldoc);
145 my $perl = OpenSRF::Utils::SettingsParser::XML2perl( $mods->documentElement );
146 return $perl->{mods} if exists($perl->{mods});
151 # ---------------------------------------------------------------------------
152 # Initializes a MARC -> Unified MODS batch process
153 # ---------------------------------------------------------------------------
154 sub _start_mods_batch {
155 my( $self, $master_doc ) = @_;
156 $self->{master_doc} = $self->_marcxml_to_perl( $master_doc );
159 sub start_mods_batch {
160 my( $self, $master_doc ) = @_;
161 my $xmldoc = $parser->parse_string( $master_doc );
162 my $mods = $mods_sheet->transform($xmldoc);
163 $self->{master_doc} = OpenILS::Application::WORM->modsdoc_to_values( $mods );
164 $self->{master_doc} = $utils->mods_values_to_mods_slim( $self->{master_doc} );
165 $self->{master_doc}->{isbn} = OpenILS::Application::WORM::_get_field_value( $mods, $isbn_xpath );
166 $self->{master_doc}->{type_of_resource} =
167 [ OpenILS::Application::WORM::_get_field_value( $mods, $resource_xpath ) ];
170 # ---------------------------------------------------------------------------
171 # Takes a MARCXML string an adds it to the growing MODS doc
172 # ---------------------------------------------------------------------------
173 sub push_mods_batch {
174 my( $self, $marcxml ) = @_;
176 my $xmldoc = $parser->parse_string($marcxml);
177 my $mods = $mods_sheet->transform($xmldoc);
178 my $xmlperl = OpenILS::Application::WORM->modsdoc_to_values( $mods );
179 $xmlperl = $utils->mods_values_to_mods_slim( $xmlperl );
181 for my $subject( @{$xmlperl->{subject}} ) {
182 push @{$self->{master_doc}->{subject}}, $subject;
185 push( @{$self->{master_doc}->{type_of_resource}},
186 OpenILS::Application::WORM::_get_field_value( $mods, $resource_xpath ));
188 if(!($self->{master_doc}->{isbn}) ) {
189 $self->{master_doc}->{isbn} =
190 OpenILS::Application::WORM::_get_field_value( $mods, $isbn_xpath );
195 # ---------------------------------------------------------------------------
196 # Completes a MARC -> Unified MODS batch process and returns the perl hash
197 # ---------------------------------------------------------------------------
198 sub finish_mods_batch {
200 my $perl = $self->{master_doc};
201 $self->{master_doc} = undef;