enabling immutable finishing porting Log and stats
[catagits/Catalyst-Runtime.git] / lib / Catalyst / DispatchType / Path.pm
1 package Catalyst::DispatchType::Path;
2
3 use Moose;
4 extends 'Catalyst::DispatchType';
5
6 #use strict;
7 #use base qw/Catalyst::DispatchType/;
8 use Text::SimpleTable;
9 use URI;
10
11 has _paths => (
12                is => 'rw',
13                isa => 'HashRef',
14                required => 1,
15                default => sub { +{} },
16               );
17
18 =head1 NAME
19
20 Catalyst::DispatchType::Path - Path DispatchType
21
22 =head1 SYNOPSIS
23
24 See L<Catalyst>.
25
26 =head1 DESCRIPTION
27
28 =head1 METHODS
29
30 =head2 $self->list($c)
31
32 Debug output for Path dispatch points
33
34 =cut
35
36 sub list {
37     my ( $self, $c ) = @_;
38     my $paths = Text::SimpleTable->new( [ 35, 'Path' ], [ 36, 'Private' ] );
39     foreach my $path ( sort keys %{ $self->_paths } ) {
40         my $display_path = $path eq '/' ? $path : "/$path";
41         foreach my $action ( @{ $self->_paths->{$path} } ) {
42             $paths->row( $display_path, "/$action" );
43         }
44     }
45     $c->log->debug( "Loaded Path actions:\n" . $paths->draw . "\n" )
46       if ( keys %{ $self->_paths } );
47 }
48
49 =head2 $self->match( $c, $path )
50
51 For each action registered to this exact path, offers the action a chance to
52 match the path (in the order in which they were registered). Succeeds on the
53 first action that matches, if any; if not, returns 0.
54
55 =cut
56
57 sub match {
58     my ( $self, $c, $path ) = @_;
59
60     $path ||= '/';
61
62     foreach my $action ( @{ $self->_paths->{$path} || [] } ) {
63         next unless $action->match($c);
64         $c->req->action($path);
65         $c->req->match($path);
66         $c->action($action);
67         $c->namespace( $action->namespace );
68         return 1;
69     }
70
71     return 0;
72 }
73
74 =head2 $self->register( $c, $action )
75
76 Calls register_path for every Path attribute for the given $action.
77
78 =cut
79
80 sub register {
81     my ( $self, $c, $action ) = @_;
82
83     my @register = @{ $action->attributes->{Path} || [] };
84
85     $self->register_path( $c, $_, $action ) for @register;
86
87     return 1 if @register;
88     return 0;
89 }
90
91 =head2 $self->register_path($c, $path, $action)
92
93 Registers an action at a given path.
94
95 =cut
96
97 sub register_path {
98     my ( $self, $c, $path, $action ) = @_;
99     $path =~ s!^/!!;
100     $path = '/' unless length $path;
101     $path = URI->new($path)->canonical;
102
103     unshift( @{ $self->_paths->{$path} ||= [] }, $action);
104
105     return 1;
106 }
107
108 =head2 $self->uri_for_action($action, $captures)
109
110 get a URI part for an action; always returns undef is $captures is set
111 since Path actions don't have captures
112
113 =cut
114
115 sub uri_for_action {
116     my ( $self, $action, $captures ) = @_;
117
118     return undef if @$captures;
119
120     if (my $paths = $action->attributes->{Path}) {
121         my $path = $paths->[0];
122         $path = '/' unless length($path);
123         $path = "/${path}" unless ($path =~ m/^\//);
124         $path = URI->new($path)->canonical;
125         return $path;
126     } else {
127         return undef;
128     }
129 }
130
131 =head1 AUTHOR
132
133 Matt S Trout
134 Sebastian Riedel, C<sri@cpan.org>
135
136 =head1 COPYRIGHT
137
138 This program is free software, you can redistribute it and/or modify it under
139 the same terms as Perl itself.
140
141 =cut
142
143 __PACKAGE__->meta->make_immutable;
144
145 1;