Reverted stupidity workaround
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Base.pm
1 package Catalyst::Base;
2
3 use strict;
4 use base qw/Catalyst::Component Catalyst::AttrContainer Class::Accessor::Fast/;
5
6 use Catalyst::Exception;
7 use Catalyst::Utils;
8 use Class::Inspector;
9 use NEXT;
10
11 __PACKAGE__->mk_classdata($_) for qw/_dispatch_steps/;
12
13 __PACKAGE__->_dispatch_steps( [qw/_BEGIN _AUTO _ACTION/] );
14
15 sub _DISPATCH : Private {
16     my ( $self, $c ) = @_;
17
18     foreach my $disp ( @{ $self->_dispatch_steps } ) {
19         last unless $c->forward($disp);
20     }
21
22     $c->forward('_END');
23 }
24
25 sub _BEGIN : Private {
26     my ( $self, $c ) = @_;
27     my $begin = ( $c->get_actions( 'begin', $c->namespace ) )[-1];
28     return 1 unless $begin;
29     $begin->execute($c);
30     return !@{ $c->error };
31 }
32
33 sub _AUTO : Private {
34     my ( $self, $c ) = @_;
35     my @auto = $c->get_actions( 'auto', $c->namespace );
36     foreach my $auto (@auto) {
37         $auto->execute($c);
38         return 0 unless $c->state;
39     }
40     return 1;
41 }
42
43 sub _ACTION : Private {
44     my ( $self, $c ) = @_;
45     $c->action->execute($c);
46     return !@{ $c->error };
47 }
48
49 sub _END : Private {
50     my ( $self, $c ) = @_;
51     my $end = ( $c->get_actions( 'end', $c->namespace ) )[-1];
52     return 1 unless $end;
53     $end->execute($c);
54     return !@{ $c->error };
55 }
56
57 sub action_namespace {
58     my ( $self, $c ) = @_;
59     return Catalyst::Utils::class2prefix( ref $self,
60         $c->config->{case_sensitive} )
61       || '';
62 }
63
64 sub register_actions {
65     my ( $self, $c ) = @_;
66     my $class = ref $self || $self;
67     my $namespace = $self->action_namespace($c);
68     my %methods;
69     $methods{ $self->can($_) } = $_
70       for @{ Class::Inspector->methods($class) || [] };
71
72     # Advanced inheritance support for plugins and the like
73     my @action_cache;
74     {
75         no strict 'refs';
76         for my $isa ( @{"$class\::ISA"}, $class ) {
77             push @action_cache, @{ $isa->_action_cache }
78               if $isa->can('_action_cache');
79         }
80     }
81
82     foreach my $cache (@action_cache) {
83         my $code   = $cache->[0];
84         my $method = $methods{$code};
85         next unless $method;
86         my $attrs = $self->_parse_attrs( @{ $cache->[1] } );
87         if ( $attrs->{Private} && ( keys %$attrs > 1 ) ) {
88             $c->log->debug( 'Bad action definition "'
89                   . join( ' ', @{ $cache->[1] } )
90                   . qq/" for "$class->$method"/ )
91               if $c->debug;
92             next;
93         }
94         my $reverse = $namespace ? "$namespace/$method" : $method;
95         my $action = Catalyst::Action->new(
96             {
97                 name       => $method,
98                 code       => $code,
99                 reverse    => $reverse,
100                 namespace  => $namespace,
101                 class      => $class,
102                 attributes => $attrs,
103             }
104         );
105         $c->dispatcher->register( $c, $action );
106     }
107 }
108
109 sub _parse_attrs {
110     my ( $self, @attrs ) = @_;
111     my %attributes;
112     foreach my $attr (@attrs) {
113
114         # Parse out :Foo(bar) into Foo => bar etc (and arrayify)
115
116         if ( my ( $key, $value ) = ( $attr =~ /^(.*?)(?:\(\s*(.+)\s*\))?$/ ) ) {
117
118             if ( defined $value ) {
119                 ( $value =~ s/^'(.*)'$/$1/ ) || ( $value =~ s/^"(.*)"/$1/ );
120             }
121             push( @{ $attributes{$key} }, $value );
122         }
123     }
124     return \%attributes;
125 }
126
127 =head1 NAME
128
129 Catalyst::Base - Catalyst Controller Base Class
130
131 =head1 SYNOPSIS
132
133
134 =head1 DESCRIPTION
135
136
137 =head1 METHODS
138
139 =over 4
140
141 =back
142
143 =head1 SEE ALSO
144
145 L<Catalyst>.
146
147 =head1 AUTHOR
148
149 Sebastian Riedel, C<sri@cpan.org>
150 Marcus Ramberg, C<mramberg@cpan.org>
151 Matt S Trout, C<mst@shadowcatsystems.co.uk>
152
153 =head1 COPYRIGHT
154
155 This program is free software, you can redistribute it and/or modify it under
156 the same terms as Perl itself.
157
158 =cut
159
160 1;