1 package OpenILS::Application::Cat::Utils;
2 use strict; use warnings;
3 use OpenILS::Utils::Fieldmapper;
6 use OpenSRF::Utils::SettingsParser;
9 my $parser = XML::LibXML->new();
10 my $xslt = XML::LibXSLT->new();
11 my $xslt_doc = $parser->parse_file( "/pines/cvs/ILS/Open-ILS/xsl/MARC21slim2MODS.xsl" );
12 my $mods_sheet = $xslt->parse_stylesheet( $xslt_doc );
18 $class = ref($class) || $class;
19 return bless( {}, $class );
23 # ---------------------------------------------------------------------------
24 # Converts an XML nodeset into a tree
25 # This method expects a blessed Fieldmapper::biblio::record_node object
27 my($class, $nodeset) = @_;
29 for my $child (@$nodeset) {
30 next unless ($child and defined($child->parent_node));
31 my $parent = $nodeset->[$child->parent_node];
32 $parent->children([]) unless defined($parent->children);
35 push( @{$parent->children}, $child );
41 # ---------------------------------------------------------------------------
42 # Converts a tree into an xml nodeset
43 # This method expects a blessed Fieldmapper::biblio::record_node object
46 my($self, $node, $newnodes) = @_;
48 return $newnodes unless $node;
50 if(!$newnodes) { $newnodes = []; }
52 push( @$newnodes, $node );
54 if( $node->children() ) {
56 for my $child (@{ $node->children() }) {
58 new Fieldmapper::biblio::record_node ($child);
60 if(!defined($child->parent_node)) {
61 $child->parent_node($node->intra_doc_id);
62 $child->ischanged(1); #just to be sure
65 $self->tree2nodeset( $child, $newnodes );
69 $node->children([]); #we don't need them hanging around
73 # ---------------------------------------------------------------------------
74 # Walks a nodeset and checks for insert, update, and delete and makes
75 # appropriate db calls
76 # This method expects a blessed Fieldmapper::biblio::record_node object
78 my($self, $nodeset) = @_;
88 for my $index (0..$size) {
91 my $pos = $index + $offset;
92 my $node = $nodeset->[$index];
96 if($node->isdeleted()) {
98 warn "Deleting Node " . $node->intra_doc_id() . "\n";
99 push @_deleted, $node;
104 $node->intra_doc_id($pos);
105 warn "Adding Node $pos\n";
110 if( ($node->intra_doc_id()
111 and $node->intra_doc_id() != $pos) ||
112 $node->ischanged() ) {
114 warn "Updating Node " . $node->intra_doc_id() . " to $pos\n";
116 $node->intra_doc_id($pos);
117 push @_altered, $node;
126 # iterate through each list and send updates to the db
128 my $hash = { added => $a, deleted => $d, updated => $al };
134 # ---------------------------------------------------------------------------
135 # Utility method for turning a nodes_array ($nodelist->nodelist) into
137 # ---------------------------------------------------------------------------
138 sub _nodeset_to_perl {
139 my($self, $nodeset) = @_;
140 return undef unless ($nodeset);
142 OpenILS::Utils::FlatXML->new()->nodeset_to_xml( $nodeset );
144 # Evil, but for some reason necessary
145 $xmldoc = $parser->parse_string( $xmldoc->toString() );
146 return $self->marcxml_doc_to_mods_perl($xmldoc);
150 # ---------------------------------------------------------------------------
151 # Initializes a MARC -> Unified MODS batch process
152 # ---------------------------------------------------------------------------
153 sub start_mods_batch {
154 my( $self, $master_doc ) = @_;
155 $self->{master_doc} = $self->_nodeset_to_perl( $master_doc->nodeset );
158 # ---------------------------------------------------------------------------
159 # Completes a MARC -> Unified MODS batch process and returns the perl hash
160 # ---------------------------------------------------------------------------
161 sub finish_mods_batch {
163 my $perl = $self->{master_doc};
164 $self->{master_doc} = undef;
168 # ---------------------------------------------------------------------------
169 # Pushes a marcxml nodeset into the current MODS batch
170 # ---------------------------------------------------------------------------
171 sub mods_push_nodeset {
172 my( $self, $nodeset ) = @_;
173 my $xmlperl = $self->_nodeset_to_perl( $nodeset->nodeset );
174 for my $subject( @{$xmlperl->{subject}} ) {
175 push @{$self->{master_doc}->{subject}}, $subject;
181 # ---------------------------------------------------------------------------
182 # Transforms a MARC21SLIM XML document into a MODS formatted perl hash
183 # ---------------------------------------------------------------------------
184 sub marcxml_doc_to_mods_perl {
185 my( $self, $marcxml_doc ) = @_;
186 my $mods = $mods_sheet->transform($marcxml_doc);
187 my $perl = OpenSRF::Utils::SettingsParser::XML2perl( $mods->documentElement );
188 return $perl->{mods} if $perl;
194 # ---------------------------------------------------------------------------
195 # Transforms a set of marcxml nodesets into a unified MODS perl hash. The
196 # first doc is assumed to be the 'master'
197 # ---------------------------------------------------------------------------
198 sub marcxml_nodeset_list_to_mods_perl {
199 my( $self, $nodeset_list ) = @_;
200 my $master = $self->_nodeset_to_perl( shift(@$nodeset_list) );
202 for my $nodes (@$nodeset_list) {
203 my $xmlperl = $self->_nodeset_to_perl( $nodes );
204 for my $subject( @{$xmlperl->{subject}} ) {
205 push @{$master->{subject}}, $subject;
213 # not really sure if we'll ever need this one...
214 sub marcxml_doc_to_mods_nodeset {
215 my( $self, $marcxml_doc ) = @_;
216 my $mods = $mods_sheet->transform($marcxml_doc);
217 my $u = OpenILS::Utils::FlatXML->new();
218 my $nodeset = $u->xmldoc_to_nodeset( $mods );
219 return $nodeset->nodeset if $nodeset;