File Coverage

blib/lib/MasonX/Resolver/PAR.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package MasonX::Resolver::PAR;
2              
3             $VERSION = '0.2';
4              
5 1     1   18597 use strict;
  1         3  
  1         43  
6              
7 1     1   1859 use Apache;
  0            
  0            
8             use Apache::Server;
9             use Archive::Zip qw(:ERROR_CODES :CONSTANTS);
10             use Params::Validate qw(:all);
11              
12             use HTML::Mason::ComponentSource;
13             use MasonX::Component::ParBased;
14             use HTML::Mason::Resolver;
15             use base qw(HTML::Mason::Resolver);
16              
17             use HTML::Mason::Exceptions (abbr => ['param_error']);
18              
19             __PACKAGE__->valid_params
20             (
21             par_file => { parse => 'string', type => SCALAR },
22             par_files_path => { parse => 'string', type => SCALAR, default=>'htdocs/' },
23             par_static_directory_index => { type => ARRAYREF, default => [ qw( index.htm index.html ) ] },
24              
25             );
26              
27             sub new {
28             my $class = shift;
29             my $self = $class->SUPER::new(@_);
30             my $parfile = $self->{par_file};
31             my $filepath = $self->{par_files_path};
32             $filepath.= '/' if ($filepath !~ /\/$/);
33             my $zip = Archive::Zip->new($parfile);
34             if ($zip) {
35             die "No $filepath in $parfile" unless
36             $zip->memberNamed ($filepath);
37             } else {
38             param_error "$parfile must be executable";
39             }
40             $self->{par_files_path}=$filepath;
41             return $self;
42             }
43              
44              
45             # Internal method to retrieve a list of Archive::Zip members
46             # representing the files requested. takes a regexp as input
47             sub _get_files {
48             my ($self, $path) = @_;
49             my $par=$self->{par_file};
50             my $filepath=$self->{par_files_path};
51             my $zip = Archive::Zip->new($par);
52             if ($zip) {
53             my @conf_members=$zip->membersMatching($filepath.$path);
54             return @conf_members if @conf_members;
55             }
56             return ;
57             }
58              
59              
60             # Internal method to retrieve a Archive::Zip member representing the file
61             sub _get_file {
62             my ($self, $path) = @_;
63             $path =~ s/^\///;
64             my $par=$self->{par_file};
65             my $filepath=$self->{par_files_path};
66             my $zip = Archive::Zip->new($par);
67             if ($zip) {
68             my $conf_member=$zip->memberNamed($filepath.$path);
69             return $conf_member if $conf_member;
70             }
71             return undef;
72             }
73              
74             sub get_info {
75             my ($self, $path) = @_;
76             my $content=$self->_get_file($path);
77             return unless $content;
78             my ($last_mod) =$content->lastModTime;
79             return unless $last_mod;
80             my $base=$self->{par_file};
81             $base =~ s/^.*\///;
82              
83             return
84             HTML::Mason::ComponentSource->new
85             (
86             friendly_name => "$base$path",
87             comp_id => "$base$path",
88             last_modified => $last_mod,
89             comp_path => $path,
90             comp_class => "MasonX::Component::ParBased",
91             source_callback => sub { $self->_get_source($path) },
92             # extra => { comp_root => 'par' },
93             );
94             }
95              
96             sub _get_source {
97             my ($self, $path) = @_;
98             my $content=$self->_get_file($path);
99             return unless $content;
100             return $content->contents;
101             }
102              
103             sub glob_path {
104             my $self = shift;
105             my $pattern = shift;
106              
107             $pattern =~~ s/\*/\[\/\]\*/g;
108              
109             return
110             $self->_get_files($pattern);
111             }
112              
113             # Translate apache request object to a component path
114             sub apache_request_to_comp_path {
115              
116             my $self = shift;
117             my $r = shift;
118             #FIXME: These should be imported from Apache's settings
119             my @indices=@{$self->{par_static_directory_index}};
120             #we base this on path_info
121             my $path = ( $r->path_info ? $r->path_info : "/" );
122             my $file=$self->_get_file($path);
123             if ($file) {
124             return $path unless $file->isDirectory;
125             if ($file->isDirectory()) { #then we add index path
126             $path.= '/' if ($path !~ /\/$/);
127             foreach my $index (@indices) {
128             return $path.$index if $self->_get_file($path.$index);
129             }
130             }
131             return undef;
132             }
133             return $path;
134             }
135              
136             1;
137              
138             __END__