File Coverage

blib/lib/AxKit2/Processor.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             # Copyright 2001-2006 The Apache Software Foundation
2             #
3             # Licensed under the Apache License, Version 2.0 (the "License");
4             # you may not use this file except in compliance with the License.
5             # You may obtain a copy of the License at
6             #
7             # http://www.apache.org/licenses/LICENSE-2.0
8             #
9             # Unless required by applicable law or agreed to in writing, software
10             # distributed under the License is distributed on an "AS IS" BASIS,
11             # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12             # See the License for the specific language governing permissions and
13             # limitations under the License.
14             #
15              
16             # A "Processor" is responsible for controlling XML transformations
17              
18             package AxKit2::Processor;
19              
20 9     9   51 use strict;
  9         13  
  9         308  
21 9     9   47 use warnings;
  9         13  
  9         244  
22              
23 9     9   45 use Exporter ();
  9         19  
  9         490  
24              
25             our @ISA = qw(Exporter);
26             our @EXPORT = qw(XSP XSLT TAL XPathScript);
27              
28 9     9   6970 use XML::LibXML;
  0            
  0            
29             use AxKit2::Transformer::XSP;
30             use AxKit2::Utils qw(bytelength);
31              
32             our $parser = XML::LibXML->new();
33              
34             # ->new($path [, $input]);
35             sub new {
36             my $class = shift; $class = ref($class) if ref($class);
37             my $client = shift || die "A processor needs a client";
38             my $path = shift || die "A processor needs source document path";
39            
40             my $self = bless {client => $client, path => $path}, $class;
41            
42             @_ and $self->{input} = shift;
43             @_ and $self->{output} = shift;
44            
45             return $self;
46             }
47              
48             sub path {
49             my $self = shift;
50             $self->{path};
51             }
52              
53             sub input {
54             my $self = shift;
55             $self->{input};
56             }
57              
58             sub client {
59             my $self = shift;
60             $self->{client};
61             }
62              
63             sub dom {
64             my $self = shift;
65             @_ and $self->{input} = shift;
66            
67             my $input = $self->{input}
68             || do { open(my $fh, $self->{path})
69             || die "open($self->{path}): $!";
70             die "open($self->{path}): directory" if -d $fh;
71             $fh };
72            
73             if (ref($input) eq 'XML::LibXML::Document') {
74             return $input;
75             }
76             elsif (ref($input) eq 'GLOB') {
77             # parse $fh
78             return $self->{input} = $parser->parse_fh($input);
79             }
80             else {
81             # assume string
82             return $self->{input} = $parser->parse_string($input);
83             }
84             }
85              
86             sub output {
87             my $self = shift;
88             my $client = $self->{client};
89            
90             if ($self->{output}) {
91             $self->{output}->($client, $self->dom);
92             }
93             else {
94             my $out = $self->dom->toString;
95             $client->headers_out->header('Content-Length', bytelength($out));
96             $client->headers_out->header('Content-Type', 'text/xml');
97             $client->send_http_headers;
98             $client->write($out);
99             }
100             }
101              
102             sub str_to_transform {
103             my $str = shift;
104             ref($str) and return $str;
105             if ($str =~ /^(TAL|XSP|XSLT)\((.*)\)/) {
106             return $1->($2);
107             }
108             else {
109             die "Unknown transform type: $str";
110             }
111             }
112              
113             sub transform {
114             my $self = shift;
115             my @transforms = map { str_to_transform($_) } @_;
116            
117             my $pos = 0;
118             my ($dom, $outfunc);
119             for my $trans (@transforms) {
120             $trans->client($self->client);
121             if ($AxKit2::Processor::DumpIntermediate) {
122             mkdir("/tmp/axtrace");
123             open(my $fh, ">/tmp/axtrace/trace.$pos");
124             print $fh ($dom || $self->dom)->toString;
125             }
126             ($dom, $outfunc) = $trans->transform($pos++, $self);
127             # $trans->client(undef);
128             $self->dom($dom);
129             }
130            
131             return $self->new($self->client, $self->path, $dom, $outfunc);
132             }
133              
134             # Exported transformer functions. These are really just short cuts for
135             # calling the transformer constructors.
136              
137             sub XSP {
138             die "XSP takes no arguments" if @_;
139             return AxKit2::Transformer::XSP->new();
140             }
141              
142             sub XSLT {
143             my $stylesheet = shift || die "XSLT requires a stylesheet";
144             require AxKit2::Transformer::XSLT;
145             return AxKit2::Transformer::XSLT->new($stylesheet, @_);
146             }
147              
148             sub TAL {
149             my $stylesheet = shift || die "TAL requires a stylesheet";
150             require AxKit2::Transformer::TAL;
151             return AxKit2::Transformer::TAL->new($stylesheet, @_);
152             }
153              
154             sub XPathScript {
155             my $stylesheet = shift || die "XPathScript requires a stylesheet";
156             require AxKit2::Transformer::XPathScript;
157             my $output_style = shift;
158             return AxKit2::Transformer::XPathScript->new($stylesheet, $output_style);
159             }
160              
161             1;
162              
163             __END__