File Coverage

blib/lib/HTML/Location.pm
Criterion Covered Total %
statement 65 66 98.4
branch 18 28 64.2
condition 2 6 33.3
subroutine 19 19 100.0
pod 7 7 100.0
total 111 126 88.1


line stmt bran cond sub pod time code
1             package HTML::Location;
2              
3             =pod
4              
5             =head1 NAME
6              
7             HTML::Location - Working with disk to URI file mappings (deprecated: see URI::ToDisk)
8              
9             =head1 STATUS
10              
11             As correctly noted by several users, C is a really stupid
12             name for this module. I apologise, I was new to the whole CPAN game at the
13             time I first wrote it.
14              
15             B to L. This module will
16             remain indefinately for back-compatibility, but should otherwise be
17             B.
18              
19             Please convert your code to the otherwise identical L at
20             your leisure.
21              
22             =head1 SYNOPSIS
23              
24             # We have a directory on disk that is accessible via a web server
25             my $authors = HTML::Location->new( '/var/www/AUTHORS', 'http://ali.as/AUTHORS' );
26            
27             # We know where a particular generated file needs to go
28             my $about = $authors->catfile( 'A', 'AD', 'ADAMK', 'about.html' );
29            
30             # Save the file to disk
31             my $file = $about->path;
32             open( FILE, ">$file" ) or die "open: $!";
33             print FILE, $content;
34             close FILE;
35            
36             # Show the user where to see the file
37             my $uri = $about->uri;
38             print "Author information is at $uri\n";
39              
40             =head1 DESCRIPTION
41              
42             In several process relating to working with the web, we may need to keep
43             track of an area of disk that maps to a particular URL. From this location,
44             we should be able to derived both a filesystem path and URL for any given
45             directory or file under this location that we might need to work with.
46              
47             =head2 Implementation
48              
49             Internally each C object contains both a filesystem path,
50             which is altered using L, and a L object. When making a
51             change, the path section of the URI is altered using .
52              
53             =head2 Method Calling Conventions
54              
55             The main functional methods, such as C and C, do B
56             modify the original object, instead returning a new object containing the
57             new location.
58              
59             This means that it should be used in a somewhat similar way to L.
60              
61             # The File::Spec way
62             my $path = '/some/path';
63             $path = File::Spec->catfile( $path, 'some', 'file.txt' );
64            
65             # The HTML::Location way
66             my $location = HTML::Location->new( '/some/path', 'http://foo.com/blah' );
67             $location = $location->catfile( 'some', 'file.txt' );
68              
69             OK, well it's not exactly THAT close, but you get the idea. It also allows you
70             to do method chaining, which is basically
71              
72             HTML::Location->new( '/foo', 'http://foo.com/' )->catfile( 'bar.txt' )->uri
73              
74             Which may seem a little trivial now, but I expect it to get more useful later.
75             It also means you can do things like this.
76              
77             my $base = HTML::Location->new( '/my/cache', 'http://foo.com/' );
78             foreach my $path ( @some_files ) {
79             my $file = $base->catfile( $path );
80             print $file->path . ': ' . $file->uri . "\n";
81             }
82              
83             In the above example, you don't have to be continuously cloning the location,
84             because all that stuff happens internally as needed.
85              
86             =head1 METHODS
87              
88             =cut
89              
90 2     2   27077 use strict;
  2         4  
  2         70  
91 2     2   1475 use Clone ();
  2         7211  
  2         45  
92 2     2   212298 use URI ();
  2         14323  
  2         46  
93 2     2   18 use File::Spec ();
  2         3  
  2         28  
94 2     2   11 use File::Spec::Unix ();
  2         3  
  2         68  
95              
96             # Overload stringification to the string form of the URL.
97 2     2   11 use overload 'bool' => sub () { 1 };
  2         4  
  2         8  
98 2     2   100 use overload '""' => 'uri';
  2         3  
  2         8  
99 2     2   87 use overload 'eq' => '__eq';
  2         3  
  2         8  
100              
101 2     2   97 use vars qw{$VERSION @ISA};
  2         5  
  2         127  
102             BEGIN {
103 2     2   12 $VERSION = '1.03';
104 2         1319 @ISA = 'Clone';
105             }
106              
107              
108              
109              
110              
111             #####################################################################
112             # Constructors
113              
114             =pod
115              
116             =head2 new $path, $http_url
117              
118             The C constructor takes as argument a filesystem path and a http(s)
119             URL. Both are required, and the method will return C is either is
120             illegal. The URL is not required to have protocol, host or port sections,
121             and as such allows for host-relative URL to be used.
122              
123             Returns a new C object on success, or C on failure.
124              
125             =cut
126              
127             sub new {
128 6     6 1 42 my $class = shift;
129              
130             # Get the base file system path
131 6 50       53 my $path = File::Spec->canonpath(shift) or return undef;
132              
133             # Get the base URI. We only accept HTTP(s) URLs
134 6 50 33     36 return undef unless defined $_[0] and ! ref $_[0];
135 6 50       31 my $URI = URI->new( shift, 'http' ) or return undef;
136 6 50       9551 $URI->path( '/' ) unless length $URI->path;
137              
138             # Create the object
139 6         224 bless { path => $path, URI => $URI }, $class;
140             }
141              
142             =pod
143              
144             =head2 param $various
145              
146             C is provided as a mechanism for higher order modules to flexibly
147             accept HTML::Location's as parameters. In this case, it accepts either
148             an existing HTML::Location object, two arguments ($path, $http_url), or
149             a reference to an array containing the same two arguments.
150              
151             Returns a HTML::Location if possible, or C if one cannot be provided.
152              
153             =cut
154              
155             sub param {
156 3     3 1 1298 my $class = shift;
157 3 100       20 return shift if UNIVERSAL::isa(ref $_[0], 'HTML::Location');
158 2 100       11 return HTML::Location->new(@_) if @_ == 2;
159 1 50 33     6 if ( ref $_[0] eq 'ARRAY' and @{$_[0]} ) {
  1         5  
160 1         2 return HTML::Location->new(@{$_[0]});
  1         4  
161             }
162 0         0 undef;
163             }
164              
165              
166              
167              
168              
169             #####################################################################
170             # Accessors
171              
172             =pod
173              
174             =head2 uri
175              
176             The C method gets and returns the current URI of the location, in
177             string form.
178              
179             =cut
180              
181             sub uri {
182 62     62 1 13656 $_[0]->{URI}->as_string;
183             }
184              
185             =pod
186              
187             =head2 URI
188              
189             The capitalised C method gets and returns a copy of the raw L,
190             held internally by the location. Note that only a copy is returned, and
191             as such as safe to further modify yourself without effecting the location.
192              
193             =cut
194              
195             sub URI {
196 32     32 1 593 Clone::clone $_[0]->{URI};
197             }
198              
199             =pod
200              
201             =head2 path
202              
203             The C method returns the filesystem path componant of the location.
204              
205             =cut
206              
207 44     44 1 3156 sub path { $_[0]->{path} }
208              
209              
210              
211              
212              
213             #####################################################################
214             # Manipulate Locations
215              
216             =pod
217              
218             =head2 catdir 'dir', 'dir', ...
219              
220             A L workalike, the C method acts in the same way as for
221             L, modifying both componants of the location. The C method
222             returns a B HTML::Location object representing the new location, or
223             C on error.
224              
225             =cut
226              
227             sub catdir {
228 1     1 1 320 my $self = shift;
229 1         3 my @args = @_;
230              
231             # Alter the URI and local paths
232 1 50       7 my $new_uri = File::Spec::Unix->catdir( $self->{URI}->path, @args ) or return undef;
233 1 50       29 my $new_path = File::Spec->catdir( $self->{path}, @args ) or return undef;
234              
235             # Clone and set the new values
236 1         11 my $changed = $self->clone;
237 1         3 $changed->{URI}->path( $new_uri );
238 1         27 $changed->{path} = $new_path;
239              
240 1         4 $changed;
241             }
242              
243             =pod
244              
245             =head2 catfile [ 'dir', ..., ] $file
246              
247             Like C, the C method acts in the same was as for
248             L, and returns a new HTML::Location object representing
249             the file, or C on error.
250              
251             =cut
252              
253             sub catfile {
254 1     1 1 5985 my $self = shift;
255 1         4 my @args = @_;
256              
257             # Alter the URI and local paths
258 1 50       91 my $uri = File::Spec::Unix->catfile( $self->{URI}->path, @args ) or return undef;
259 1 50       40 my $fs = File::Spec->catfile( $self->{path}, @args ) or return undef;
260              
261             # Set both and return
262 1         14 my $changed = $self->clone;
263 1         5 $changed->{URI}->path( $uri );
264 1         23 $changed->{path} = $fs;
265              
266 1         3 $changed;
267             }
268              
269              
270              
271              
272              
273             #####################################################################
274             # Additional Overload Methods
275              
276             sub __eq {
277 14 50   14   1934 my $left = UNIVERSAL::isa(ref $_[0], 'HTML::Location') ? shift : return '';
278 14 100       54 my $right = UNIVERSAL::isa(ref $_[0], 'HTML::Location') ? shift : return '';
279 10 100       22 ($left->path eq $right->path) and ($left->uri eq $right->uri);
280             }
281              
282              
283              
284              
285              
286             #####################################################################
287             # Coercion Support
288              
289 1     1   3 sub __as_URI { shift->URI }
290              
291             1;
292              
293             =pod
294              
295             =head1 TO DO
296              
297             Add more File::Spec-y methods as needed. Ask if you need one.
298              
299             =head1 SUPPORT
300              
301             Bugs should be reported via the CPAN bug tracker at
302              
303             L
304              
305             For other issues, or commercial enhancement or support, contact the author.
306              
307             =head1 AUTHOR
308              
309             Adam Kennedy Eadamk@cpan.orgE
310              
311             =head1 COPYRIGHT
312              
313             Copyright 2003 - 2008 Adam Kennedy.
314              
315             This program is free software; you can redistribute
316             it and/or modify it under the same terms as Perl itself.
317              
318             The full text of the license can be found in the
319             LICENSE file included with this module.
320              
321             =cut