Don't run the moose controller test if Moose isn't available
[catagits/Catalyst-Runtime.git] / lib / Catalyst / DispatchType / Regex.pm
CommitLineData
b96f127f 1package Catalyst::DispatchType::Regex;
2
3use strict;
6b239949 4use base qw/Catalyst::DispatchType::Path/;
8c113188 5use Text::SimpleTable;
e73e3bad 6use Catalyst::Utils;
ea0e58d9 7use Text::Balanced ();
b96f127f 8
2633d7dc 9=head1 NAME
b96f127f 10
2633d7dc 11Catalyst::DispatchType::Regex - Regex DispatchType
b96f127f 12
2633d7dc 13=head1 SYNOPSIS
14
15See L<Catalyst>.
16
17=head1 DESCRIPTION
18
19=head1 METHODS
20
b5ecfcf0 21=head2 $self->list($c)
a9cbd748 22
4ab87e27 23Output a table of all regex actions, and their private equivalent.
24
a9cbd748 25=cut
26
27sub list {
28 my ( $self, $c ) = @_;
e73e3bad 29 my $column_width = Catalyst::Utils::term_width() - 35 - 9;
30 my $re = Text::SimpleTable->new( [ 35, 'Regex' ], [ $column_width, 'Private' ] );
a9cbd748 31 for my $regex ( @{ $self->{compiled} } ) {
694d15f1 32 my $action = $regex->{action};
dcc61a75 33 $re->row( $regex->{path}, "/$action" );
a9cbd748 34 }
1cf0345b 35 $c->log->debug( "Loaded Regex actions:\n" . $re->draw . "\n" )
8c113188 36 if ( @{ $self->{compiled} } );
a9cbd748 37}
38
b5ecfcf0 39=head2 $self->match( $c, $path )
2633d7dc 40
b2b90ec2 41Checks path against every compiled regex, and offers the action for any regex
42which matches a chance to match the request. If it succeeds, sets action,
43match and captures on $c->req and returns 1. If not, returns 0 without
44altering $c.
4ab87e27 45
2633d7dc 46=cut
47
48sub match {
49 my ( $self, $c, $path ) = @_;
50
51 return if $self->SUPER::match( $c, $path );
52
53 # Check path against plain text first
54
55 foreach my $compiled ( @{ $self->{compiled} || [] } ) {
2982e768 56 if ( my @captures = ( $path =~ $compiled->{re} ) ) {
4082e678 57 next unless $compiled->{action}->match($c);
2633d7dc 58 $c->req->action( $compiled->{path} );
b96f127f 59 $c->req->match($path);
2982e768 60 $c->req->captures( \@captures );
2633d7dc 61 $c->action( $compiled->{action} );
11bd4e3e 62 $c->namespace( $compiled->{action}->namespace );
b96f127f 63 return 1;
64 }
65 }
66
67 return 0;
68}
69
b5ecfcf0 70=head2 $self->register( $c, $action )
2633d7dc 71
b2b90ec2 72Registers one or more regex actions for an action object.
4ab87e27 73Also registers them as literal paths.
74
b2b90ec2 75Returns 1 if any regexps were registered.
4ab87e27 76
2633d7dc 77=cut
78
79sub register {
b96f127f 80 my ( $self, $c, $action ) = @_;
34d28dfd 81 my $attrs = $action->attributes;
27708fc5 82 my @register = @{ $attrs->{'Regex'} || [] };
081def36 83
b96f127f 84 foreach my $r (@register) {
081def36 85 $self->register_path( $c, $r, $action );
86 $self->register_regex( $c, $r, $action );
b96f127f 87 }
27708fc5 88
694d15f1 89 return 1 if @register;
90 return 0;
b96f127f 91}
92
b5ecfcf0 93=head2 $self->register_regex($c, $re, $action)
081def36 94
4ab87e27 95Register an individual regex on the action. Usually called from the
b2b90ec2 96register method.
4ab87e27 97
081def36 98=cut
99
100sub register_regex {
101 my ( $self, $c, $re, $action ) = @_;
102 push(
103 @{ $self->{compiled} }, # and compiled regex for us
104 {
105 re => qr#$re#,
106 action => $action,
107 path => $re,
108 }
109 );
110}
111
ea0e58d9 112=head2 $self->uri_for_action($action, $captures)
113
114returns a URI for this action if it can find a regex attributes that contains
115the correct number of () captures. Note that this may function incorrectly
116in the case of nested captures - if your regex does (...(..))..(..) you'll
117need to pass the first and third captures only.
118
119=cut
120
121sub uri_for_action {
122 my ( $self, $action, $captures ) = @_;
123
124 if (my $regexes = $action->attributes->{Regex}) {
125 REGEX: foreach my $orig (@$regexes) {
126 my $re = "$orig";
127 $re =~ s/^\^//;
128 $re =~ s/\$$//;
129 my $final = '/';
130 my @captures = @$captures;
131 while (my ($front, $rest) = split(/\(/, $re, 2)) {
132 ($rest, $re) =
133 Text::Balanced::extract_bracketed("(${rest}", '(');
134 next REGEX unless @captures;
135 $final .= $front.shift(@captures);
136 }
137 next REGEX if @captures;
138 return $final;
139 }
140 }
141 return undef;
142}
143
0bf7ab71 144=head1 AUTHORS
2633d7dc 145
0bf7ab71 146Catalyst Contributors, see Catalyst.pm
2633d7dc 147
148=head1 COPYRIGHT
149
150This program is free software, you can redistribute it and/or modify it under
151the same terms as Perl itself.
152
153=cut
154
b96f127f 1551;