1 package OpenILS::WWW::IDL2js;
2 use strict; use warnings;
5 use Apache2::Const -compile => qw(OK DECLINED HTTP_INTERNAL_SERVER_ERROR);
6 use Apache2::RequestRec;
7 use Apache2::SubRequest;
13 use OpenSRF::Utils::SettingsClient;
19 # load and parse the stylesheet
25 # parse the IDL, loaded from the network
30 OpenSRF::System->bootstrap_client(config_file => $bs_config);
31 my $sclient = OpenSRF::Utils::SettingsClient->new();
33 my $xsl_file = $sclient->config_value('IDL2js');
36 warn "XSL2js XSL file required for IDL2js Apache module\n";
40 $xsl_file = $sclient->config_value(dirs => 'xsl')."/$xsl_file";
41 my $idl_file = $sclient->config_value("IDL");
43 my $xslt = XML::LibXSLT->new();
47 my $style_doc = XML::LibXML->load_xml(location => $xsl_file, no_cdata=>1);
48 $stylesheet = $xslt->parse_stylesheet($style_doc);
52 warn "Invalid XSL File: $xsl_file: $e\n";
55 return Apache2::Const::OK;
62 my $args = $r->args || '';
63 child_init() unless $__initted;
65 return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR unless $stylesheet;
67 # pull the locale from the query string if present
68 (my $locale = $args) =~ s/.*locale=([a-z]{2}-[A-Z]{2}).*/$1/g;
70 # remove the locale argument from the query
71 # string, regardless of whether it was valid
72 $args =~ s/([&;]?locale=[^&;]*)[&;]?//g;
74 # if no valid locale is present in the query
75 # string, pull it from the headers
76 $locale = $r->headers_in->get('Accept-Language') unless $locale;
78 if (!$locale or $locale !~ /^[a-z]{2}-[A-Z]{2}$/) {
79 $r->log->debug("Invalid IDL2js locale '$locale'; using en-US");
83 $r->log->debug("IDL2js using locale '$locale'");
86 my $stat = load_IDL($r, $locale, $args, \$output);
87 return $stat unless $stat == Apache2::Const::OK;
89 $r->content_type('application/x-javascript; encoding=utf8');
91 return Apache2::Const::OK;
94 # loads the IDL for the provided locale.
95 # when possible, use a cached version of the IDL.
97 my ($r, $locale, $args, $output_ref) = @_;
99 # do we already have a cached copy of the IDL for this locale?
100 if (!$args and $idl_cache{$locale}) {
101 $$output_ref = $idl_cache{$locale};
102 return Apache2::Const::OK;
105 # Fetch the locale-aware fm_IDL.xml via Apache subrequest.
106 my $subr = $r->lookup_uri("/reports/fm_IDL.xml?locale=$locale");
108 # filter allows us to capture the output of the subrequest locally
109 # http://www.gossamer-threads.com/lists/modperl/modperl/97649#97649
111 $subr->add_output_filter(sub {
113 while (my $e = $bb->first) {
118 return Apache2::Const::OK;
124 $r->log->error("No IDL XML found");
125 return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
130 my $idl_doc = XML::LibXML->load_xml(string => $xml);
131 my $results = $stylesheet->transform($idl_doc, class_list => "'$args'");
132 $output = $stylesheet->output_as_bytes($results);
135 $r->log->error("IDL XSL Error: $e");
138 return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR unless $output;
140 # only cache full versions of the IDL
141 $idl_cache{$locale} = $output unless $args;
143 # pass output back to the caller
144 $$output_ref = $output;
146 return Apache2::Const::OK;