]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/lib/OpenILS/WWW/SuperCat/Feed.pm
Merge branch 'master' of git.evergreen-ils.org:Evergreen-DocBook into doc_consolidati...
[working/Evergreen.git] / Open-ILS / src / perlmods / lib / OpenILS / WWW / SuperCat / Feed.pm
1 package OpenILS::WWW::SuperCat::Feed;
2 use strict; use warnings;
3 use vars qw/$parser/;
4 use OpenSRF::EX qw(:try);
5 use XML::LibXML;
6 use XML::LibXSLT;
7 use OpenSRF::Utils::SettingsClient;
8 use CGI;
9 use DateTime;
10 use DateTime::Format::Mail;
11
12
13 sub exists {
14         my $class = shift;
15         my $type = shift;
16
17         return 1 if UNIVERSAL::can("OpenILS::WWW::SuperCat::Feed::$type" => 'new');
18         return 0;
19 }
20
21 sub new {
22         my $class = shift;
23         my $type = shift;
24         if ($type) {
25                 $class .= '::'.$type;
26                 return $class->new;
27         }
28         throw OpenSRF::EX::ERROR ("I need a feed type!") ;
29 }
30
31 sub build {
32         my $class = shift;
33         my $xml = shift;
34         return undef unless $xml;
35
36         $parser = new XML::LibXML if (!$parser);
37
38         my $self = { doc => $parser->parse_string($xml), items => [] };
39
40         $self = bless $self => $class;
41         $self->{count} = 0;
42         return $self;
43 }
44
45 sub type {
46         my $self = shift;
47         my $type = shift;
48         $self->{type} = $type if ($type);
49         return $self->{type};
50 }
51
52 sub count {
53         my $self = shift;
54         return $self->{count};
55 }
56
57 sub search {
58         my $self = shift;
59         my $search = shift;
60         $self->{search} = $search if ($search);
61         return $self->{search};
62 }
63
64 sub class {
65         my $self = shift;
66         my $search = shift;
67         $self->{class} = $search if ($search);
68         return $self->{class};
69 }
70
71 sub Sort {
72         my $self = shift;
73         my $search = shift;
74         $self->{sort} = $search if ($search);
75         return $self->{sort};
76 }
77
78 sub SortDir {
79         my $self = shift;
80         my $search = shift;
81         $self->{sort_dir} = $search if ($search);
82         return $self->{sort_dir};
83 }
84
85 sub lang {
86         my $self = shift;
87         my $search = shift;
88         $self->{lang} = $search if ($search);
89         return $self->{lang};
90 }
91
92 sub lib {
93         my $self = shift;
94         my $lib = shift;
95         $self->{lib} = $lib if ($lib);
96         return $self->{lib};
97 }
98
99 sub base {
100         my $self = shift;
101         my $base = shift;
102         $self->{base} = $base if ($base);
103         return $self->{base};
104 }
105
106 sub root {
107         my $self = shift;
108         my $root = shift;
109         $self->{root} = $root if ($root);
110         return $self->{root};
111 }
112
113 sub unapi {
114         my $self = shift;
115         my $unapi = shift;
116         $self->{unapi} = $unapi if ($unapi);
117         return $self->{unapi};
118 }
119
120 sub push_item {
121         my $self = shift;
122         $self->{count} += scalar(@_);
123         push @{ $self->{items} }, @_;
124 }
125
126 sub items {
127         my $self = shift;
128         return @{ $self->{items} } if (wantarray);
129         return $self->{items};
130 }
131
132 sub _add_node {
133         my $self = shift;
134
135         my $xpath = shift;
136         my $new = shift;
137
138         for my $node ($self->{doc}->findnodes($xpath)) {
139                 $node->appendChild($new);
140                 last;
141         }
142 }
143
144 sub _create_node {
145         my $self = shift;
146
147         my $xpath = shift;
148         my $ns = shift;
149         my $name = shift;
150         my $text = shift;
151         my $attrs = shift;
152
153         for my $node ($self->{doc}->findnodes($xpath)) {
154                 my $new = $self->{doc}->createElement($name) if (!$ns);
155                 $new = $self->{doc}->createElementNS($ns,$name) if ($ns);
156
157                 $new->appendChild( $self->{doc}->createTextNode( $text ) )
158                         if (defined $text);
159
160                 if (ref($attrs)) {
161                         for my $key (keys %$attrs) {
162                                 next unless $$attrs{$key};
163                                 $new->setAttribute( $key => $$attrs{$key} );
164                         }
165                 }
166
167                 $node->appendChild( $new );
168
169                 return $new;
170         }
171 }
172
173 sub add_item {
174         my $self = shift;
175         my $class = ref($self) || $self;
176         $class .= '::item';
177
178         my $item_xml = shift;
179         my $entry = $class->new($item_xml);
180         return undef unless $entry;
181
182         $entry->base($self->base);
183         $entry->unapi($self->unapi);
184
185         $self->push_item($entry);
186         return $entry;
187 }
188
189 sub add_holdings {
190         my $self = shift;
191         my $holdings_xml = shift;
192
193         return $self unless ($holdings_xml);
194
195         $parser = new XML::LibXML if (!$parser);
196         my $new_doc = $parser->parse_string($holdings_xml);
197
198         for my $root ( $self->{doc}->findnodes($self->{holdings_xpath}) ) {
199                 $root->appendChild($new_doc->documentElement);
200                 last;
201         }
202         return $self;
203 }
204
205 sub composeDoc {
206         my $self = shift;
207         for my $root ( $self->{doc}->findnodes($self->{item_xpath}) ) {
208                 for my $item ( $self->items ) {
209                         $root->appendChild( $item->{doc}->documentElement );
210                 }
211                 last;
212         }
213 }
214
215 sub toString {
216         my $self = shift;
217         $self->composeDoc;
218         return $self->{doc}->toString(1);
219 }
220
221 sub id {};
222 sub link {};
223 sub title {};
224 sub update_ts {};
225 sub creator {};
226
227 #----------------------------------------------------------
228
229 package OpenILS::WWW::SuperCat::Feed::atom;
230 use base 'OpenILS::WWW::SuperCat::Feed';
231 use OpenSRF::Utils qw/:datetime/;
232
233 sub new {
234         my $class = shift;
235         my $self = $class->SUPER::build('<feed xmlns:atom="http://www.w3.org/2005/Atom"/>');
236         $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', undef);
237         $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', 'atom');
238         $self->{type} = 'application/atom+xml';
239         $self->{item_xpath} = '/atom:feed';
240         return $self;
241 }
242
243 sub title {
244         my $self = shift;
245         my $text = shift;
246         $self->_create_node('/atom:feed','http://www.w3.org/2005/Atom','title', $text);
247 }
248
249 sub update_ts {
250         my $self = shift;
251         # ATOM demands RFC-3339 compliant datetime formats
252         my $text = shift || gmtime_ISO8601();
253         $self->_create_node($self->{item_xpath},'http://www.w3.org/2005/Atom','updated', $text);
254 }
255
256 sub creator {
257         my $self = shift;
258         my $text = shift;
259         $self->_create_node('/atom:feed','http://www.w3.org/2005/Atom','author');
260         $self->_create_node('/atom:feed/atom:author', 'http://www.w3.org/2005/Atom','name', $text);
261 }
262
263 sub link {
264         my $self = shift;
265         my $type = shift;
266         my $id = shift;
267         my $mime = shift || "application/x-$type+xml";
268         my $title = shift;
269
270         $type = 'self' if ($type eq 'atom');
271
272         $self->_create_node(
273                 $self->{item_xpath},
274                 'http://www.w3.org/2005/Atom',
275                 'link',
276                 undef,
277                 { rel => $type,
278                   href => $id,
279                   title => $title,
280                   type => $mime,
281                 }
282         );
283 }
284
285 sub id {
286         my $self = shift;
287         my $id = shift;
288
289         $self->_create_node( $self->{item_xpath}, 'http://www.w3.org/2005/Atom', 'id', $id );
290 }
291
292 package OpenILS::WWW::SuperCat::Feed::atom::item;
293 use base 'OpenILS::WWW::SuperCat::Feed::atom';
294
295 sub new {
296         my $class = shift;
297         my $xml = shift;
298         my $self = $class->SUPER::build($xml);
299         $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', undef);
300         $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', 'atom');
301         $self->{item_xpath} = '/atom:entry';
302         $self->{holdings_xpath} = '/atom:entry';
303         $self->{type} = 'application/atom+xml';
304         return $self;
305 }
306
307
308 #----------------------------------------------------------
309
310 package OpenILS::WWW::SuperCat::Feed::rss2;
311 use base 'OpenILS::WWW::SuperCat::Feed';
312
313 sub new {
314         my $class = shift;
315         my $self = $class->SUPER::build('<rss version="2.0"><channel/></rss>');
316         $self->{type} = 'application/rss+xml';
317         $self->{item_xpath} = '/rss/channel';
318         return $self;
319 }
320
321 sub title {
322         my $self = shift;
323         my $text = shift;
324         $self->_create_node('/rss/channel',undef,'title', $text);
325 }
326
327 sub description {
328         my $self = shift;
329         my $text = shift;
330         $self->_create_node('/rss/channel',undef,'description', $text);
331 }
332
333 sub update_ts {
334         my $self = shift;
335         # RSS2 demands RFC-822 compliant datetime formats
336         my $text = shift || DateTime::Format::Mail->format_datetime(DateTime->now());
337         $self->_create_node($self->{item_xpath},undef,'lastBuildDate', $text);
338 }
339
340 sub creator {
341         my $self = shift;
342         my $text = shift;
343         $self->_create_node('/rss/channel', undef,'generator', $text);
344 }
345
346 sub link {
347         my $self = shift;
348         my $type = shift;
349         my $id = shift;
350         my $mime = shift || "application/x-$type+xml";
351
352         if ($type eq 'rss2' or $type eq 'alternate') {
353                 # Just link to ourself using standard RSS2 link element
354                 $self->_create_node(
355                         $self->{item_xpath},
356                         undef,
357                         'link',
358                         $id,
359                         undef
360                 );
361         } else {
362                 # Alternate link: use XHTML link element
363                 $self->_create_node(
364                         $self->{item_xpath},
365                         'http://www.w3.org/1999/xhtml',
366                         'xhtml:link',
367                         $id,
368                         { rel => $type,
369                           type => $mime,
370                         }
371                 );
372         }
373 }
374
375 sub id {
376         my $self = shift;
377         my $id = shift;
378
379         $self->_create_node($self->{item_xpath}, undef,'guid', $id);
380 }
381
382 package OpenILS::WWW::SuperCat::Feed::rss2::item;
383 use base 'OpenILS::WWW::SuperCat::Feed::rss2';
384
385 sub new {
386         my $class = shift;
387         my $xml = shift;
388         my $self = $class->SUPER::build($xml);
389         $self->{type} = 'application/rss+xml';
390         $self->{item_xpath} = '/item';
391         $self->{holdings_xpath} = '/item';
392         return $self;
393 }
394
395 sub update_ts {
396         my $self = shift;
397         # RSS2 demands RFC-822 compliant datetime formats
398         my $text = shift;
399         if (!$text) {
400                 # No date passed in, default to now
401                 $text = DateTime::Format::Mail->format_datetime(DateTime->now());
402         } elsif ($text =~ m/^\s*(\d{4})\.?\s*$/o) {
403                 # Publication date is just a year, convert accordingly
404                 my $year = DateTime->new(year=>$1);
405                 $text = DateTime::Format::Mail->format_datetime($year);
406         }
407         $self->_create_node($self->{item_xpath},undef,'pubDate', $text);
408 }
409
410 sub id {
411         my $self = shift;
412         my $id = shift;
413
414         $self->_create_node(
415                 $self->{item_xpath},
416                 undef,
417                 'guid',
418                 $id,
419                 {
420                         isPermaLink=>"false"
421                 }
422         );
423 }
424
425 #----------------------------------------------------------
426
427 package OpenILS::WWW::SuperCat::Feed::mods;
428 use base 'OpenILS::WWW::SuperCat::Feed';
429
430 sub new {
431         my $class = shift;
432         my $self = $class->SUPER::build('<modsCollection version="3.0" xmlns="http://www.loc.gov/mods/" xmlns:mods="http://www.loc.gov/mods/"/>');
433         $self->{type} = 'application/xml';
434         $self->{item_xpath} = '/mods:modsCollection';
435         return $self;
436 }
437
438 package OpenILS::WWW::SuperCat::Feed::mods::item;
439 use base 'OpenILS::WWW::SuperCat::Feed::mods';
440
441 sub new {
442         my $class = shift;
443         my $xml = shift;
444         my $self = $class->SUPER::build($xml);
445         $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/', 'mods');
446         $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/', undef, 1);
447         $self->{type} = 'application/xml';
448         $self->{holdings_xpath} = '/mods:mods';
449         return $self;
450 }
451
452 my $linkid = 1;
453
454 sub link {
455         my $self = shift;
456         my $type = shift;
457         my $id = shift;
458
459         if ($type eq 'unapi' || $type eq 'opac') {
460                 $self->_create_node(
461                         'mods:mods',
462             undef,
463                         'relatedItem',
464                         undef,
465                         { type => 'otherFormat', id => 'link-'.$linkid }
466                 );
467                 $self->_create_node(
468                         "mods:mods/relatedItem[\@id='link-$linkid']",
469             undef,
470                         'recordIdentifier',
471                         $id
472                 );
473                 $linkid++;
474         }
475 }
476
477 #----------------------------------------------------------
478
479 package OpenILS::WWW::SuperCat::Feed::mods3;
480 use base 'OpenILS::WWW::SuperCat::Feed::mods';
481
482 sub new {
483         my $class = shift;
484         my $self = $class->SUPER::build('<modsCollection version="3.0" xmlns="http://www.loc.gov/mods/v3" xmlns:mods="http://www.loc.gov/mods/v3"/>');
485         $self->{type} = 'application/xml';
486         $self->{item_xpath} = '/mods:modsCollection';
487         return $self;
488 }
489
490 package OpenILS::WWW::SuperCat::Feed::mods3::item;
491 use base 'OpenILS::WWW::SuperCat::Feed::mods::item';
492
493 sub new {
494         my $class = shift;
495         my $xml = shift;
496         my $self = $class->SUPER::build($xml);
497         $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/v3', 'mods');
498         $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/v3', undef, 1);
499         $self->{type} = 'application/xml';
500         $self->{holdings_xpath} = '/mods:mods';
501         return $self;
502 }
503
504 sub link {
505         my $self = shift;
506         my $type = shift;
507         my $id = shift;
508
509         if ($type eq 'unapi' || $type eq 'opac') {
510                 $self->_create_node(
511                         'mods:mods',
512                         undef,
513                         'relatedItem',
514                         undef,
515                         { type => 'otherFormat', id => 'link-'.$linkid }
516                 );
517                 $self->_create_node(
518                         "mods:mods/relatedItem[\@id='link-$linkid']",
519                         undef,
520                         'recordIdentifier',
521                         $id
522                 );
523                 $linkid++;
524         }
525 }
526
527
528 #----------------------------------------------------------
529
530 package OpenILS::WWW::SuperCat::Feed::mods32;
531 use base 'OpenILS::WWW::SuperCat::Feed::mods3';
532
533 sub new {
534         my $class = shift;
535         my $self = $class->SUPER::build('<modsCollection version="3.2" xmlns="http://www.loc.gov/mods/v3" xmlns:mods="http://www.loc.gov/mods/v3"/>');
536         $self->{type} = 'application/xml';
537         $self->{item_xpath} = '/mods:modsCollection';
538         return $self;
539 }
540
541 package OpenILS::WWW::SuperCat::Feed::mods32::item;
542 use base 'OpenILS::WWW::SuperCat::Feed::mods3::item';
543
544 #----------------------------------------------------------
545
546 package OpenILS::WWW::SuperCat::Feed::mods33;
547 use base 'OpenILS::WWW::SuperCat::Feed::mods3';
548
549 sub new {
550         my $class = shift;
551         my $self = $class->SUPER::build('<modsCollection version="3.3" xmlns="http://www.loc.gov/mods/v3" xmlns:mods="http://www.loc.gov/mods/v3"/>');
552         $self->{type} = 'application/xml';
553         $self->{item_xpath} = '/mods:modsCollection';
554         return $self;
555 }
556
557 package OpenILS::WWW::SuperCat::Feed::mods33::item;
558 use base 'OpenILS::WWW::SuperCat::Feed::mods3::item';
559
560
561 #----------------------------------------------------------
562
563 package OpenILS::WWW::SuperCat::Feed::marcxml;
564 use base 'OpenILS::WWW::SuperCat::Feed';
565
566 sub new {
567         my $class = shift;
568         my $self = $class->SUPER::build('<collection xmlns="http://www.loc.gov/MARC21/slim" xmlns:marc="http://www.loc.gov/MARC21/slim"/>');
569         $self->{type} = 'application/xml';
570         $self->{item_xpath} = '/marc:collection';
571         return $self;
572 }
573 sub link {
574         my $self = shift;
575         my $type = shift;
576         my $id = shift;
577
578         if ($type eq 'unapi') {
579                 $self->_create_node(
580                         'marc:collection',
581                         'http://www.w3.org/1999/xhtml',
582                         'xhtml:link',
583                         undef,
584                         { rel => 'unapi-server', href => $id, title => "unapi" }
585                 );
586                 $linkid++;
587         }
588 }
589
590
591 package OpenILS::WWW::SuperCat::Feed::marcxml::item;
592 use base 'OpenILS::WWW::SuperCat::Feed::marcxml';
593
594 sub new {
595         my $class = shift;
596         my $xml = shift;
597         my $self = $class->SUPER::build($xml);
598         return undef unless $self;
599         $self->{doc}->documentElement->setNamespace('http://www.loc.gov/MARC21/slim', undef);
600         $self->{type} = 'application/xml';
601         $self->{holdings_xpath} = '/*[local-name()="record"]';
602         return $self;
603 }
604
605 sub link {
606         my $self = shift;
607         my $type = shift;
608         my $id = shift;
609
610         if ($type eq 'opac') {
611                 $self->_create_node(
612                         '*[local-name()="record"]',
613                         'http://www.w3.org/1999/xhtml',
614                         'xhtml:link',
615                         undef,
616                         { rel => 'otherFormat', href => $id, title => "Dynamic Details" }
617                 );
618                 $linkid++;
619         } elsif ($type eq 'unapi-id') {
620                 $self->_create_node(
621                         '*[local-name()="record"]',
622                         'http://www.w3.org/1999/xhtml',
623                         'xhtml:abbr',
624                         undef,
625                         {  title => $id, class => "unapi-id" }
626                 );
627                 $linkid++;
628         }
629 }
630
631
632 #----------------------------------------------------------
633
634 package OpenILS::WWW::SuperCat::Feed::html;
635 use base 'OpenILS::WWW::SuperCat::Feed::atom';
636
637 sub new {
638         my $class = shift;
639         my $self = $class->SUPER::new;
640         $self->type('text/html');
641         return $self;
642 }
643
644 our ($_parser, $_xslt, $xslt_file);
645
646 sub toString {
647         my $self = shift;
648         my $base = $self->base || '';
649         my $root = $self->root || '';
650         my $search = $self->search || '';
651         my $class = $self->class || '';
652         my $lib = $self->lib || '-';
653
654         $self->composeDoc;
655
656         $_parser ||= new XML::LibXML;
657         $_xslt ||= new XML::LibXSLT;
658
659         $xslt_file ||=
660                 OpenSRF::Utils::SettingsClient
661                         ->new
662                         ->config_value( dirs => 'xsl' ).
663                 "/ATOM2XHTML.xsl";
664
665         # parse the MODS xslt ...
666         my $atom2html_xslt = $_xslt->parse_stylesheet( $_parser->parse_file($xslt_file) );
667
668         my $new_doc = $atom2html_xslt->transform(
669                 $self->{doc},
670                 base_dir => "'$root'",
671                 lib => "'$lib'",
672                 searchTerms => "'$search'",
673                 searchClass => "'$class'",
674         );
675
676         return $new_doc->toString(1); 
677 }
678
679
680 package OpenILS::WWW::SuperCat::Feed::html::item;
681 use base 'OpenILS::WWW::SuperCat::Feed::atom::item';
682
683 #----------------------------------------------------------
684
685 package OpenILS::WWW::SuperCat::Feed::htmlcard;
686 use base 'OpenILS::WWW::SuperCat::Feed::marcxml';
687
688 sub new {
689         my $class = shift;
690         my $self = $class->SUPER::new;
691         $self->type('text/html');
692         $self->{xsl} = "/MARC21slim2HTMLCard.xsl";
693         return $self;
694 }
695
696 our ($_parser, $_xslt, $xslt_file);
697
698 sub toString {
699         my $self = shift;
700         my $base = $self->base || '';
701         my $root = $self->root || '';
702         my $search = $self->search || '';
703         my $sort = $self->Sort || '';
704         my $sort_dir = $self->SortDir || '';
705         my $lang = $self->lang || '';
706         my $lib = $self->lib || '-';
707
708         $self->composeDoc;
709
710         $_parser ||= new XML::LibXML;
711         $_xslt ||= new XML::LibXSLT;
712
713         $xslt_file =
714                 OpenSRF::Utils::SettingsClient
715                         ->new
716                         ->config_value( dirs => 'xsl' ).$self->{xsl};
717
718         # parse the MODS xslt ...
719         my $atom2html_xslt = $_xslt->parse_stylesheet( $_parser->parse_file($xslt_file) );
720
721         my $new_doc = $atom2html_xslt->transform(
722                 $self->{doc},
723                 base_dir => "'$root'",
724                 lib => "'$lib'",
725                 searchTerms => "'$search'",
726                 searchSort => "'$sort'",
727                 searchSortDir => "'$sort_dir'",
728                 searchLang => "'$lang'",
729         );
730
731         return $new_doc->toString(1); 
732 }
733
734 package OpenILS::WWW::SuperCat::Feed::htmlcard::item;
735 use base 'OpenILS::WWW::SuperCat::Feed::marcxml::item';
736
737 package OpenILS::WWW::SuperCat::Feed::htmlholdings;
738 use base 'OpenILS::WWW::SuperCat::Feed::htmlcard';
739
740 sub new {
741         my $class = shift;
742         my $self = $class->SUPER::new;
743         $self->{xsl} = "/MARC21slim2HTMLCard-holdings.xsl";
744         return $self;
745 }
746
747 package OpenILS::WWW::SuperCat::Feed::htmlholdings::item;
748 use base 'OpenILS::WWW::SuperCat::Feed::htmlcard::item';
749
750
751 package OpenILS::WWW::SuperCat::Feed::marctxt;
752 use base 'OpenILS::WWW::SuperCat::Feed::marcxml';
753
754 sub new {
755         my $class = shift;
756         my $self = $class->SUPER::new;
757         $self->{type} = 'text/plain';
758         $self->{xsl} = "/MARC21slim2MARCtxt.xsl";
759         return $self;
760 }
761
762
763 our ($_parser, $_xslt, $xslt_file);
764
765 sub toString {
766         my $self = shift;
767         my $base = $self->base || '';
768         my $root = $self->root || '';
769         my $search = $self->search || '';
770         my $class = $self->class || '';
771         my $lib = $self->lib || '-';
772
773         $self->composeDoc;
774
775         $_parser ||= new XML::LibXML;
776         $_xslt ||= new XML::LibXSLT;
777
778         $xslt_file ||=
779                 OpenSRF::Utils::SettingsClient
780                         ->new
781                         ->config_value( dirs => 'xsl' ).
782                 $self->{xsl};
783
784         # parse the MARC text xslt ...
785         my $marctxt_xslt = $_xslt->parse_stylesheet( $_parser->parse_file($xslt_file) );
786
787         my $new_doc = $marctxt_xslt->transform(
788                 $self->{doc},
789                 base_dir => "'$root'",
790                 lib => "'$lib'",
791                 searchTerms => "'$search'",
792                 searchClass => "'$class'",
793         );
794
795         return $marctxt_xslt->output_string($new_doc); 
796 }
797
798
799 package OpenILS::WWW::SuperCat::Feed::marctxt::item;
800 use base 'OpenILS::WWW::SuperCat::Feed::marcxml::item';
801
802
803 package OpenILS::WWW::SuperCat::Feed::ris;
804 use base 'OpenILS::WWW::SuperCat::Feed::marcxml';
805
806 sub new {
807         my $class = shift;
808         my $self = $class->SUPER::new;
809         $self->{type} = 'text/plain';
810         $self->{xsl} = "/MARC21slim2RIS.xsl";
811         return $self;
812 }
813
814
815 our ($_parser, $_xslt, $xslt_file);
816
817 sub toString {
818         my $self = shift;
819         my $base = $self->base || '';
820         my $root = $self->root || '';
821         my $search = $self->search || '';
822         my $class = $self->class || '';
823         my $lib = $self->lib || '-';
824
825         $self->composeDoc;
826
827         $_parser ||= new XML::LibXML;
828         $_xslt ||= new XML::LibXSLT;
829
830         $xslt_file ||=
831                 OpenSRF::Utils::SettingsClient
832                         ->new
833                         ->config_value( dirs => 'xsl' ).
834                 $self->{xsl};
835
836         # parse the MARC text xslt ...
837         my $ris_xslt = $_xslt->parse_stylesheet( $_parser->parse_file($xslt_file) );
838
839         my $new_doc = $ris_xslt->transform(
840                 $self->{doc},
841                 base_dir => "'$root'",
842                 lib => "'$lib'",
843                 searchTerms => "'$search'",
844                 searchClass => "'$class'",
845         );
846
847         return $ris_xslt->output_string($new_doc); 
848 }
849
850
851 package OpenILS::WWW::SuperCat::Feed::ris::item;
852 use base 'OpenILS::WWW::SuperCat::Feed::marcxml::item';
853
854
855 1;