Upgrade that debug statement to a warning + test we get the warning we expect to
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
1 package Catalyst;
2
3 use Moose;
4 extends 'Catalyst::Component';
5 use bytes;
6 use Scope::Upper ();
7 use Catalyst::Exception;
8 use Catalyst::Log;
9 use Catalyst::Request;
10 use Catalyst::Request::Upload;
11 use Catalyst::Response;
12 use Catalyst::Utils;
13 use Catalyst::Controller;
14 use Devel::InnerPackage ();
15 use File::stat;
16 use Module::Pluggable::Object ();
17 use Text::SimpleTable ();
18 use Path::Class::Dir ();
19 use Path::Class::File ();
20 use URI ();
21 use URI::http;
22 use URI::https;
23 use Tree::Simple qw/use_weak_refs/;
24 use Tree::Simple::Visitor::FindByUID;
25 use Class::C3::Adopt::NEXT;
26 use attributes;
27 use utf8;
28 use Carp qw/croak carp shortmess/;
29
30 BEGIN { require 5.008001; }
31
32 has stack => (is => 'ro', default => sub { [] });
33 has stash => (is => 'rw', default => sub { {} });
34 has state => (is => 'rw', default => 0);
35 has stats => (is => 'rw');
36 has action => (is => 'rw');
37 has counter => (is => 'rw', default => sub { {} });
38 has request => (is => 'rw', default => sub { $_[0]->request_class->new({}) }, required => 1, lazy => 1);
39 has response => (is => 'rw', default => sub { $_[0]->response_class->new({}) }, required => 1, lazy => 1);
40 has namespace => (is => 'rw');
41
42 sub depth { scalar @{ shift->stack || [] }; }
43 sub comp { shift->component(@_) }
44
45 sub req {
46     # carp "the use of req() is deprecated in favour of request()";
47     my $self = shift; return $self->request(@_);
48 }
49 sub res {
50     # carp "the use of res() is deprecated in favour of response()";
51     my $self = shift; return $self->response(@_);
52 }
53
54 # For backwards compatibility
55 sub finalize_output { shift->finalize_body(@_) };
56
57 # For statistics
58 our $COUNT     = 1;
59 our $START     = time;
60 our $RECURSION = 1000;
61 our $DETACH    = "catalyst_detach\n";
62 our $GO        = "catalyst_go\n";
63
64 #I imagine that very few of these really need to be class variables. if any.
65 #maybe we should just make them attributes with a default?
66 __PACKAGE__->mk_classdata($_)
67   for qw/components arguments dispatcher engine log dispatcher_class
68   engine_class context_class request_class response_class stats_class 
69   setup_finished/;
70
71 __PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
72 __PACKAGE__->engine_class('Catalyst::Engine::CGI');
73 __PACKAGE__->request_class('Catalyst::Request');
74 __PACKAGE__->response_class('Catalyst::Response');
75 __PACKAGE__->stats_class('Catalyst::Stats');
76
77 # Remember to update this in Catalyst::Runtime as well!
78
79 our $VERSION = '5.8000_06';
80 $VERSION = eval $VERSION;
81
82 sub import {
83     my ( $class, @arguments ) = @_;
84
85     # We have to limit $class to Catalyst to avoid pushing Catalyst upon every
86     # callers @ISA.
87     return unless $class eq 'Catalyst';
88
89     my $caller = caller();
90     return if $caller eq 'main';
91
92     # Kill Adopt::NEXT warnings if we're a non-RC version
93     if ($VERSION !~ /_\d{2}$/) {
94         Class::C3::Adopt::NEXT->unimport(qr/^Catalyst::/);
95     }
96
97     my $meta = Moose::Meta::Class->initialize($caller);
98     #Moose->import({ into => $caller }); #do we want to do this?
99
100     unless ( $caller->isa('Catalyst') ) {
101         my @superclasses = ($meta->superclasses, $class, 'Catalyst::Controller');
102         $meta->superclasses(@superclasses);
103     }
104     unless( $meta->has_method('meta') ){
105         $meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } );
106     }
107
108     $caller->arguments( [@arguments] );
109     $caller->setup_home;
110 }
111
112 =head1 NAME
113
114 Catalyst - The Elegant MVC Web Application Framework
115
116 =head1 SYNOPSIS
117
118 See the L<Catalyst::Manual> distribution for comprehensive
119 documentation and tutorials.
120
121     # Install Catalyst::Devel for helpers and other development tools
122     # use the helper to create a new application
123     catalyst.pl MyApp
124
125     # add models, views, controllers
126     script/myapp_create.pl model MyDatabase DBIC::Schema create=static dbi:SQLite:/path/to/db
127     script/myapp_create.pl view MyTemplate TT
128     script/myapp_create.pl controller Search
129
130     # built in testserver -- use -r to restart automatically on changes
131     # --help to see all available options
132     script/myapp_server.pl
133
134     # command line testing interface
135     script/myapp_test.pl /yada
136
137     ### in lib/MyApp.pm
138     use Catalyst qw/-Debug/; # include plugins here as well
139     
140     ### In lib/MyApp/Controller/Root.pm (autocreated)
141     sub foo : Global { # called for /foo, /foo/1, /foo/1/2, etc.
142         my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
143         $c->stash->{template} = 'foo.tt'; # set the template
144         # lookup something from db -- stash vars are passed to TT
145         $c->stash->{data} = 
146           $c->model('Database::Foo')->search( { country => $args[0] } );
147         if ( $c->req->params->{bar} ) { # access GET or POST parameters
148             $c->forward( 'bar' ); # process another action
149             # do something else after forward returns            
150         }
151     }
152     
153     # The foo.tt TT template can use the stash data from the database
154     [% WHILE (item = data.next) %]
155         [% item.foo %]
156     [% END %]
157     
158     # called for /bar/of/soap, /bar/of/soap/10, etc.
159     sub bar : Path('/bar/of/soap') { ... }
160
161     # called for all actions, from the top-most controller downwards
162     sub auto : Private { 
163         my ( $self, $c ) = @_;
164         if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication
165             $c->res->redirect( '/login' ); # require login
166             return 0; # abort request and go immediately to end()
167         }
168         return 1; # success; carry on to next action
169     }
170     
171     # called after all actions are finished
172     sub end : Private { 
173         my ( $self, $c ) = @_;
174         if ( scalar @{ $c->error } ) { ... } # handle errors
175         return if $c->res->body; # already have a response
176         $c->forward( 'MyApp::View::TT' ); # render template
177     }
178
179     ### in MyApp/Controller/Foo.pm
180     # called for /foo/bar
181     sub bar : Local { ... }
182     
183     # called for /blargle
184     sub blargle : Global { ... }
185     
186     # an index action matches /foo, but not /foo/1, etc.
187     sub index : Private { ... }
188     
189     ### in MyApp/Controller/Foo/Bar.pm
190     # called for /foo/bar/baz
191     sub baz : Local { ... }
192     
193     # first Root auto is called, then Foo auto, then this
194     sub auto : Private { ... }
195     
196     # powerful regular expression paths are also possible
197     sub details : Regex('^product/(\w+)/details$') {
198         my ( $self, $c ) = @_;
199         # extract the (\w+) from the URI
200         my $product = $c->req->captures->[0];
201     }
202
203 See L<Catalyst::Manual::Intro> for additional information.
204
205 =head1 DESCRIPTION
206
207 Catalyst is a modern framework for making web applications without the
208 pain usually associated with this process. This document is a reference
209 to the main Catalyst application. If you are a new user, we suggest you
210 start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>.
211
212 See L<Catalyst::Manual> for more documentation.
213
214 Catalyst plugins can be loaded by naming them as arguments to the "use
215 Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
216 plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
217 C<My::Module>.
218
219     use Catalyst qw/My::Module/;
220
221 If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
222 fully qualify the name by using a unary plus:
223
224     use Catalyst qw/
225         My::Module
226         +Fully::Qualified::Plugin::Name
227     /;
228
229 Special flags like C<-Debug> and C<-Engine> can also be specified as
230 arguments when Catalyst is loaded:
231
232     use Catalyst qw/-Debug My::Module/;
233
234 The position of plugins and flags in the chain is important, because
235 they are loaded in the order in which they appear.
236
237 The following flags are supported:
238
239 =head2 -Debug
240
241 Enables debug output. You can also force this setting from the system
242 environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment
243 settings override the application, with <MYAPP>_DEBUG having the highest
244 priority.
245
246 =head2 -Engine
247
248 Forces Catalyst to use a specific engine. Omit the
249 C<Catalyst::Engine::> prefix of the engine name, i.e.:
250
251     use Catalyst qw/-Engine=CGI/;
252
253 =head2 -Home
254
255 Forces Catalyst to use a specific home directory, e.g.:
256
257     use Catalyst qw[-Home=/usr/mst];
258
259 This can also be done in the shell environment by setting either the
260 C<CATALYST_HOME> environment variable or C<MYAPP_HOME>; where C<MYAPP>
261 is replaced with the uppercased name of your application, any "::" in
262 the name will be replaced with underscores, e.g. MyApp::Web should use
263 MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used.
264
265 =head2 -Log
266
267     use Catalyst '-Log=warn,fatal,error';
268  
269 Specifies a comma-delimited list of log levels.
270
271 =head2 -Stats
272
273 Enables statistics collection and reporting. You can also force this setting
274 from the system environment with CATALYST_STATS or <MYAPP>_STATS. The
275 environment settings override the application, with <MYAPP>_STATS having the
276 highest priority.
277
278 e.g. 
279
280    use Catalyst qw/-Stats=1/
281
282 =head1 METHODS
283
284 =head2 INFORMATION ABOUT THE CURRENT REQUEST
285
286 =head2 $c->action
287
288 Returns a L<Catalyst::Action> object for the current action, which
289 stringifies to the action name. See L<Catalyst::Action>.
290
291 =head2 $c->namespace
292
293 Returns the namespace of the current action, i.e., the URI prefix
294 corresponding to the controller of the current action. For example:
295
296     # in Controller::Foo::Bar
297     $c->namespace; # returns 'foo/bar';
298
299 =head2 $c->request
300
301 =head2 $c->req
302
303 Returns the current L<Catalyst::Request> object, giving access to
304 information about the current client request (including parameters,
305 cookies, HTTP headers, etc.). See L<Catalyst::Request>.
306
307 =head2 REQUEST FLOW HANDLING
308
309 =head2 $c->forward( $action [, \@arguments ] )
310
311 =head2 $c->forward( $class, $method, [, \@arguments ] )
312
313 Forwards processing to another action, by its private name. If you give a
314 class name but no method, C<process()> is called. You may also optionally
315 pass arguments in an arrayref. The action will receive the arguments in
316 C<@_> and C<< $c->req->args >>. Upon returning from the function,
317 C<< $c->req->args >> will be restored to the previous values.
318
319 Any data C<return>ed from the action forwarded to, will be returned by the
320 call to forward.
321
322     my $foodata = $c->forward('/foo');
323     $c->forward('index');
324     $c->forward(qw/MyApp::Model::DBIC::Foo do_stuff/);
325     $c->forward('MyApp::View::TT');
326
327 Note that forward implies an C<<eval { }>> around the call (actually
328 C<execute> does), thus de-fatalizing all 'dies' within the called
329 action. If you want C<die> to propagate you need to do something like:
330
331     $c->forward('foo');
332     die $c->error if $c->error;
333
334 Or make sure to always return true values from your actions and write
335 your code like this:
336
337     $c->forward('foo') || return;
338
339 =cut
340
341 sub forward { my $c = shift; no warnings 'recursion'; $c->dispatcher->forward( $c, @_ ) }
342
343 =head2 $c->detach( $action [, \@arguments ] )
344
345 =head2 $c->detach( $class, $method, [, \@arguments ] )
346
347 =head2 $c->detach()
348
349 The same as C<forward>, but doesn't return to the previous action when 
350 processing is finished. 
351
352 When called with no arguments it escapes the processing chain entirely.
353
354 =cut
355
356 sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) }
357
358 =head2 $c->visit( $action [, \@arguments ] )
359
360 =head2 $c->visit( $class, $method, [, \@arguments ] )
361
362 Almost the same as C<forward>, but does a full dispatch, instead of just
363 calling the new C<$action> / C<$class-E<gt>$method>. This means that C<begin>,
364 C<auto> and the method you go to are called, just like a new request.
365
366 In addition both C<< $c->action >> and C<< $c->namespace >> are localized.
367 This means, for example, that $c->action methods such as C<name>, C<class> and
368 C<reverse> return information for the visited action when they are invoked
369 within the visited action.  This is different from the behavior of C<forward>
370 which continues to use the $c->action object from the caller action even when
371 invoked from the callee.
372
373 C<$c-E<gt>stash> is kept unchanged.
374
375 In effect, C<visit> allows you to "wrap" another action, just as it
376 would have been called by dispatching from a URL, while the analogous
377 C<go> allows you to transfer control to another action as if it had
378 been reached directly from a URL.
379
380 =cut
381
382 sub visit { my $c = shift; $c->dispatcher->visit( $c, @_ ) }
383
384 =head2 $c->go( $action [, \@arguments ] )
385
386 =head2 $c->go( $class, $method, [, \@arguments ] )
387
388 Almost the same as C<detach>, but does a full dispatch like C<visit>,
389 instead of just calling the new C<$action> /
390 C<$class-E<gt>$method>. This means that C<begin>, C<auto> and the
391 method you visit are called, just like a new request.
392
393 C<$c-E<gt>stash> is kept unchanged.
394
395 =cut
396
397 sub go { my $c = shift; $c->dispatcher->go( $c, @_ ) }
398
399 =head2 $c->response
400
401 =head2 $c->res
402
403 Returns the current L<Catalyst::Response> object, see there for details.
404
405 =head2 $c->stash
406
407 Returns a hashref to the stash, which may be used to store data and pass
408 it between components during a request. You can also set hash keys by
409 passing arguments. The stash is automatically sent to the view. The
410 stash is cleared at the end of a request; it cannot be used for
411 persistent storage (for this you must use a session; see
412 L<Catalyst::Plugin::Session> for a complete system integrated with
413 Catalyst).
414
415     $c->stash->{foo} = $bar;
416     $c->stash( { moose => 'majestic', qux => 0 } );
417     $c->stash( bar => 1, gorch => 2 ); # equivalent to passing a hashref
418     
419     # stash is automatically passed to the view for use in a template
420     $c->forward( 'MyApp::View::TT' );
421
422 =cut
423
424 around stash => sub {
425     my $orig = shift;
426     my $c = shift;
427     my $stash = $orig->($c);
428     if (@_) {
429         my $new_stash = @_ > 1 ? {@_} : $_[0];
430         croak('stash takes a hash or hashref') unless ref $new_stash;
431         foreach my $key ( keys %$new_stash ) {
432           $stash->{$key} = $new_stash->{$key};
433         }
434     }
435
436     return $stash;
437 };
438
439
440 =head2 $c->error
441
442 =head2 $c->error($error, ...)
443
444 =head2 $c->error($arrayref)
445
446 Returns an arrayref containing error messages.  If Catalyst encounters an
447 error while processing a request, it stores the error in $c->error.  This
448 method should only be used to store fatal error messages.
449
450     my @error = @{ $c->error };
451
452 Add a new error.
453
454     $c->error('Something bad happened');
455
456 =cut
457
458 sub error {
459     my $c = shift;
460     if ( $_[0] ) {
461         my $error = ref $_[0] eq 'ARRAY' ? $_[0] : [@_];
462         croak @$error unless ref $c;
463         push @{ $c->{error} }, @$error;
464     }
465     elsif ( defined $_[0] ) { $c->{error} = undef }
466     return $c->{error} || [];
467 }
468
469
470 =head2 $c->state
471
472 Contains the return value of the last executed action.
473
474 =head2 $c->clear_errors
475
476 Clear errors.  You probably don't want to clear the errors unless you are
477 implementing a custom error screen.
478
479 This is equivalent to running
480
481     $c->error(0);
482
483 =cut
484
485 sub clear_errors {
486     my $c = shift;
487     $c->error(0);
488 }
489
490 # search components given a name and some prefixes
491 sub _comp_search_prefixes {
492     my ( $c, $name, @prefixes ) = @_;
493     my $appclass = ref $c || $c;
494     my $filter   = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
495     $filter = qr/$filter/; # Compile regex now rather than once per loop
496
497     # map the original component name to the sub part that we will search against
498     my %eligible = map { my $n = $_; $n =~ s{^$appclass\::[^:]+::}{}; $_ => $n; }
499         grep { /$filter/ } keys %{ $c->components };
500
501     # undef for a name will return all
502     return keys %eligible if !defined $name;
503
504     my $query  = ref $name ? $name : qr/^$name$/i;
505     my @result = grep { $eligible{$_} =~ m{$query} } keys %eligible;
506
507     return map { $c->components->{ $_ } } @result if @result;
508
509     # if we were given a regexp to search against, we're done.
510     return if ref $name;
511
512     # regexp fallback
513     $query  = qr/$name/i;
514     @result = map { $c->components->{ $_ } } grep { $eligible{ $_ } =~ m{$query} } keys %eligible;
515
516     # no results? try against full names
517     if( !@result ) {
518         @result = map { $c->components->{ $_ } } grep { m{$query} } keys %eligible;
519     }
520
521     # don't warn if we didn't find any results, it just might not exist
522     if( @result ) {
523         # Disgusting hack to work out correct method name
524         my $warn_for = lc $prefixes[0];
525         my $msg = "Used regexp fallback for \$c->{$warn_for}('${name}'), which found '" .
526            (join '", "', @result) . "'. Relying on regexp fallback behavior for " .
527            "component resolution is unreliable and unsafe.";
528         my $short = $result[0];
529         $short =~ s/.*?Model:://;
530         my $shortmess = Carp::shortmess('');
531         if ($shortmess =~ m#Catalyst/Plugin#) {
532            $msg .= " You probably need to set '$short' instead of '${name}' in this " .
533               "plugin's config";
534         } elsif ($shortmess =~ m#Catalyst/lib/(View|Controller)#) {
535            $msg .= " You probably need to set '$short' instead of '${name}' in this " .
536               "component's config";
537         } else {
538            $msg .= " You probably meant \$c->${warn_for}('$short') instead of \$c->${warn_for}({'${name}'}), " .
539               "but if you really wanted to search, pass in a regexp as the argument " .
540               "like so: \$c->${warn_for}(qr/${name}/)";
541         }
542         $c->log->warn( "${msg}$shortmess" );
543     }
544
545     return @result;
546 }
547
548 # Find possible names for a prefix 
549 sub _comp_names {
550     my ( $c, @prefixes ) = @_;
551     my $appclass = ref $c || $c;
552
553     my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
554
555     my @names = map { s{$filter}{}; $_; } $c->_comp_search_prefixes( undef, @prefixes );
556     return @names;
557 }
558
559 # Filter a component before returning by calling ACCEPT_CONTEXT if available
560 sub _filter_component {
561     my ( $c, $comp, @args ) = @_;
562
563     if ( eval { $comp->can('ACCEPT_CONTEXT'); } ) {
564         return $comp->ACCEPT_CONTEXT( $c, @args );
565     }
566     
567     return $comp;
568 }
569
570 =head2 COMPONENT ACCESSORS
571
572 =head2 $c->controller($name)
573
574 Gets a L<Catalyst::Controller> instance by name.
575
576     $c->controller('Foo')->do_stuff;
577
578 If the name is omitted, will return the controller for the dispatched
579 action.
580
581 If you want to search for controllers, pass in a regexp as the argument.
582
583     # find all controllers that start with Foo
584     my @foo_controllers = $c->controller(qr{^Foo});
585
586
587 =cut
588
589 sub controller {
590     my ( $c, $name, @args ) = @_;
591
592     if( $name ) {
593         my @result = $c->_comp_search_prefixes( $name, qw/Controller C/ );
594         return map { $c->_filter_component( $_, @args ) } @result if ref $name;
595         return $c->_filter_component( $result[ 0 ], @args );
596     }
597
598     return $c->component( $c->action->class );
599 }
600
601 =head2 $c->model($name)
602
603 Gets a L<Catalyst::Model> instance by name.
604
605     $c->model('Foo')->do_stuff;
606
607 Any extra arguments are directly passed to ACCEPT_CONTEXT.
608
609 If the name is omitted, it will look for 
610  - a model object in $c->stash->{current_model_instance}, then
611  - a model name in $c->stash->{current_model}, then
612  - a config setting 'default_model', or
613  - check if there is only one model, and return it if that's the case.
614
615 If you want to search for models, pass in a regexp as the argument.
616
617     # find all models that start with Foo
618     my @foo_models = $c->model(qr{^Foo});
619
620 =cut
621
622 sub model {
623     my ( $c, $name, @args ) = @_;
624
625     if( $name ) {
626         my @result = $c->_comp_search_prefixes( $name, qw/Model M/ );
627         return map { $c->_filter_component( $_, @args ) } @result if ref $name;
628         return $c->_filter_component( $result[ 0 ], @args );
629     }
630
631     if (ref $c) {
632         return $c->stash->{current_model_instance} 
633           if $c->stash->{current_model_instance};
634         return $c->model( $c->stash->{current_model} )
635           if $c->stash->{current_model};
636     }
637     return $c->model( $c->config->{default_model} )
638       if $c->config->{default_model};
639
640     my( $comp, $rest ) = $c->_comp_search_prefixes( undef, qw/Model M/);
641
642     if( $rest ) {
643         $c->log->warn( Carp::shortmess('Calling $c->model() will return a random model unless you specify one of:') );
644         $c->log->warn( '* $c->config->{default_model} # the name of the default model to use' );
645         $c->log->warn( '* $c->stash->{current_model} # the name of the model to use for this request' );
646         $c->log->warn( '* $c->stash->{current_model_instance} # the instance of the model to use for this request' );
647         $c->log->warn( 'NB: in version 5.81, the "random" behavior will not work at all.' );
648     }
649
650     return $c->_filter_component( $comp );
651 }
652
653
654 =head2 $c->view($name)
655
656 Gets a L<Catalyst::View> instance by name.
657
658     $c->view('Foo')->do_stuff;
659
660 Any extra arguments are directly passed to ACCEPT_CONTEXT.
661
662 If the name is omitted, it will look for 
663  - a view object in $c->stash->{current_view_instance}, then
664  - a view name in $c->stash->{current_view}, then
665  - a config setting 'default_view', or
666  - check if there is only one view, and return it if that's the case.
667
668 If you want to search for views, pass in a regexp as the argument.
669
670     # find all views that start with Foo
671     my @foo_views = $c->view(qr{^Foo});
672
673 =cut
674
675 sub view {
676     my ( $c, $name, @args ) = @_;
677
678     if( $name ) {
679         my @result = $c->_comp_search_prefixes( $name, qw/View V/ );
680         return map { $c->_filter_component( $_, @args ) } @result if ref $name;
681         return $c->_filter_component( $result[ 0 ], @args );
682     }
683
684     if (ref $c) {
685         return $c->stash->{current_view_instance} 
686           if $c->stash->{current_view_instance};
687         return $c->view( $c->stash->{current_view} )
688           if $c->stash->{current_view};
689     }
690     return $c->view( $c->config->{default_view} )
691       if $c->config->{default_view};
692
693     my( $comp, $rest ) = $c->_comp_search_prefixes( undef, qw/View V/);
694
695     if( $rest ) {
696         $c->log->warn( 'Calling $c->view() will return a random view unless you specify one of:' );
697         $c->log->warn( '* $c->config->{default_view} # the name of the default view to use' );
698         $c->log->warn( '* $c->stash->{current_view} # the name of the view to use for this request' );
699         $c->log->warn( '* $c->stash->{current_view_instance} # the instance of the view to use for this request' );
700         $c->log->warn( 'NB: in version 5.81, the "random" behavior will not work at all.' );
701     }
702
703     return $c->_filter_component( $comp );
704 }
705
706 =head2 $c->controllers
707
708 Returns the available names which can be passed to $c->controller
709
710 =cut
711
712 sub controllers {
713     my ( $c ) = @_;
714     return $c->_comp_names(qw/Controller C/);
715 }
716
717 =head2 $c->models
718
719 Returns the available names which can be passed to $c->model
720
721 =cut
722
723 sub models {
724     my ( $c ) = @_;
725     return $c->_comp_names(qw/Model M/);
726 }
727
728
729 =head2 $c->views
730
731 Returns the available names which can be passed to $c->view
732
733 =cut
734
735 sub views {
736     my ( $c ) = @_;
737     return $c->_comp_names(qw/View V/);
738 }
739
740 =head2 $c->comp($name)
741
742 =head2 $c->component($name)
743
744 Gets a component object by name. This method is not recommended,
745 unless you want to get a specific component by full
746 class. C<< $c->controller >>, C<< $c->model >>, and C<< $c->view >>
747 should be used instead.
748
749 If C<$name> is a regexp, a list of components matched against the full
750 component name will be returned.
751
752 =cut
753
754 sub component {
755     my ( $c, $name, @args ) = @_;
756
757     if( $name ) {
758         my $comps = $c->components;
759
760         if( !ref $name ) {
761             # is it the exact name?
762             return $c->_filter_component( $comps->{ $name }, @args )
763                        if exists $comps->{ $name };
764
765             # perhaps we just omitted "MyApp"?
766             my $composed = ( ref $c || $c ) . "::${name}";
767             return $c->_filter_component( $comps->{ $composed }, @args )
768                        if exists $comps->{ $composed };
769
770             # search all of the models, views and controllers
771             my( $comp ) = $c->_comp_search_prefixes( $name, qw/Model M Controller C View V/ );
772             return $c->_filter_component( $comp, @args ) if $comp;
773         }
774
775         # This is here so $c->comp( '::M::' ) works
776         my $query = ref $name ? $name : qr{$name}i;
777
778         my @result = grep { m{$query} } keys %{ $c->components };
779         return map { $c->_filter_component( $_, @args ) } @result if ref $name;
780
781         if( $result[ 0 ] ) {
782             $c->log->warn( Carp::shortmess(qq(Found results for "${name}" using regexp fallback)) );
783             $c->log->warn( 'Relying on the regexp fallback behavior for component resolution' );
784             $c->log->warn( 'is unreliable and unsafe. You have been warned' );
785             return $c->_filter_component( $result[ 0 ], @args );
786         }
787
788         # I would expect to return an empty list here, but that breaks back-compat
789     }
790
791     # fallback
792     return sort keys %{ $c->components };
793 }
794
795 =head2 CLASS DATA AND HELPER CLASSES
796
797 =head2 $c->config
798
799 Returns or takes a hashref containing the application's configuration.
800
801     __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
802
803 You can also use a C<YAML>, C<XML> or C<Config::General> config file
804 like myapp.yml in your applications home directory. See
805 L<Catalyst::Plugin::ConfigLoader>.
806
807     ---
808     db: dsn:SQLite:foo.db
809
810
811 =cut
812
813 around config => sub {
814     my $orig = shift;
815     my $c = shift;
816
817     croak('Setting config after setup has been run is not allowed.')
818         if ( @_ and $c->setup_finished );
819
820     $c->$orig(@_);
821 };
822
823 =head2 $c->log
824
825 Returns the logging object instance. Unless it is already set, Catalyst
826 sets this up with a L<Catalyst::Log> object. To use your own log class,
827 set the logger with the C<< __PACKAGE__->log >> method prior to calling
828 C<< __PACKAGE__->setup >>.
829
830  __PACKAGE__->log( MyLogger->new );
831  __PACKAGE__->setup;
832
833 And later:
834
835     $c->log->info( 'Now logging with my own logger!' );
836
837 Your log class should implement the methods described in
838 L<Catalyst::Log>.
839
840
841 =head2 $c->debug
842
843 Overload to enable debug messages (same as -Debug option).
844
845 Note that this is a static method, not an accessor and should be overloaded
846 by declaring "sub debug { 1 }" in your MyApp.pm, not by calling $c->debug(1).
847
848 =cut
849
850 sub debug { 0 }
851
852 =head2 $c->dispatcher
853
854 Returns the dispatcher instance. See L<Catalyst::Dispatcher>.
855
856 =head2 $c->engine
857
858 Returns the engine instance. See L<Catalyst::Engine>.
859
860
861 =head2 UTILITY METHODS
862
863 =head2 $c->path_to(@path)
864
865 Merges C<@path> with C<< $c->config->{home} >> and returns a
866 L<Path::Class::Dir> object.
867
868 For example:
869
870     $c->path_to( 'db', 'sqlite.db' );
871
872 =cut
873
874 sub path_to {
875     my ( $c, @path ) = @_;
876     my $path = Path::Class::Dir->new( $c->config->{home}, @path );
877     if ( -d $path ) { return $path }
878     else { return Path::Class::File->new( $c->config->{home}, @path ) }
879 }
880
881 =head2 $c->plugin( $name, $class, @args )
882
883 Helper method for plugins. It creates a class data accessor/mutator and
884 loads and instantiates the given class.
885
886     MyApp->plugin( 'prototype', 'HTML::Prototype' );
887
888     $c->prototype->define_javascript_functions;
889     
890 B<Note:> This method of adding plugins is deprecated. The ability
891 to add plugins like this B<will be removed> in a Catalyst 5.9.
892 Please do not use this functionality in new code.
893
894 =cut
895
896 sub plugin {
897     my ( $class, $name, $plugin, @args ) = @_;
898
899     # See block comment in t/unit_core_plugin.t    
900     $class->log->warn(qq/Adding plugin using the ->plugin method is deprecated, and will be removed in Catalyst 5.9/);
901     
902     $class->_register_plugin( $plugin, 1 );
903
904     eval { $plugin->import };
905     $class->mk_classdata($name);
906     my $obj;
907     eval { $obj = $plugin->new(@args) };
908
909     if ($@) {
910         Catalyst::Exception->throw( message =>
911               qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
912     }
913
914     $class->$name($obj);
915     $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
916       if $class->debug;
917 }
918
919 =head2 MyApp->setup
920
921 Initializes the dispatcher and engine, loads any plugins, and loads the
922 model, view, and controller components. You may also specify an array
923 of plugins to load here, if you choose to not load them in the C<use
924 Catalyst> line.
925
926     MyApp->setup;
927     MyApp->setup( qw/-Debug/ );
928
929 =cut
930
931 sub setup {
932     my ( $class, @arguments ) = @_;
933     croak('Running setup more than once')
934         if ( $class->setup_finished );
935
936     unless ( $class->isa('Catalyst') ) {
937
938         Catalyst::Exception->throw(
939             message => qq/'$class' does not inherit from Catalyst/ );
940     }
941
942     if ( $class->arguments ) {
943         @arguments = ( @arguments, @{ $class->arguments } );
944     }
945
946     # Process options
947     my $flags = {};
948
949     foreach (@arguments) {
950
951         if (/^-Debug$/) {
952             $flags->{log} =
953               ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
954         }
955         elsif (/^-(\w+)=?(.*)$/) {
956             $flags->{ lc $1 } = $2;
957         }
958         else {
959             push @{ $flags->{plugins} }, $_;
960         }
961     }
962
963     $class->setup_home( delete $flags->{home} );
964
965     $class->setup_log( delete $flags->{log} );
966     $class->setup_plugins( delete $flags->{plugins} );
967     $class->setup_dispatcher( delete $flags->{dispatcher} );
968     $class->setup_engine( delete $flags->{engine} );
969     $class->setup_stats( delete $flags->{stats} );
970
971     for my $flag ( sort keys %{$flags} ) {
972
973         if ( my $code = $class->can( 'setup_' . $flag ) ) {
974             &$code( $class, delete $flags->{$flag} );
975         }
976         else {
977             $class->log->warn(qq/Unknown flag "$flag"/);
978         }
979     }
980
981     eval { require Catalyst::Devel; };
982     if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
983         $class->log->warn(<<"EOF");
984 You are running an old script!
985
986   Please update by running (this will overwrite existing files):
987     catalyst.pl -force -scripts $class
988
989   or (this will not overwrite existing files):
990     catalyst.pl -scripts $class
991
992 EOF
993     }
994     
995     if ( $class->debug ) {
996         my @plugins = map { "$_  " . ( $_->VERSION || '' ) } $class->registered_plugins;
997
998         if (@plugins) {
999             my $column_width = Catalyst::Utils::term_width() - 6;
1000             my $t = Text::SimpleTable->new($column_width);
1001             $t->row($_) for @plugins;
1002             $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" );
1003         }
1004
1005         my $dispatcher = $class->dispatcher;
1006         my $engine     = $class->engine;
1007         my $home       = $class->config->{home};
1008
1009         $class->log->debug(sprintf(q/Loaded dispatcher "%s"/, blessed($dispatcher)));
1010         $class->log->debug(sprintf(q/Loaded engine "%s"/, blessed($engine)));
1011
1012         $home
1013           ? ( -d $home )
1014           ? $class->log->debug(qq/Found home "$home"/)
1015           : $class->log->debug(qq/Home "$home" doesn't exist/)
1016           : $class->log->debug(q/Couldn't find home/);
1017     }
1018
1019     # Call plugins setup, this is stupid and evil.
1020     {
1021         no warnings qw/redefine/;
1022         local *setup = sub { };
1023         $class->setup;
1024     }
1025
1026     # Initialize our data structure
1027     $class->components( {} );
1028
1029     $class->setup_components;
1030
1031     if ( $class->debug ) {
1032         my $column_width = Catalyst::Utils::term_width() - 8 - 9;
1033         my $t = Text::SimpleTable->new( [ $column_width, 'Class' ], [ 8, 'Type' ] );
1034         for my $comp ( sort keys %{ $class->components } ) {
1035             my $type = ref $class->components->{$comp} ? 'instance' : 'class';
1036             $t->row( $comp, $type );
1037         }
1038         $class->log->debug( "Loaded components:\n" . $t->draw . "\n" )
1039           if ( keys %{ $class->components } );
1040     }
1041
1042     # Add our self to components, since we are also a component
1043     if( $class->isa('Catalyst::Controller') ){
1044       $class->components->{$class} = $class;
1045     }
1046
1047     $class->setup_actions;
1048
1049     if ( $class->debug ) {
1050         my $name = $class->config->{name} || 'Application';
1051         $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
1052     }
1053     $class->log->_flush() if $class->log->can('_flush');
1054
1055     # Make sure that the application class becomes immutable at this point, 
1056     # which ensures that it gets an inlined constructor. This means that it 
1057     # works even if the user has added a plugin which contains a new method.
1058     # Note however that we have to do the work on scope end, so that method
1059     # modifiers work correctly in MyApp (as you have to call setup _before_ 
1060     # applying modifiers).
1061     Scope::Upper::reap(sub {
1062         my $meta = Class::MOP::get_metaclass_by_name($class);
1063         $meta->make_immutable unless $meta->is_immutable;
1064     }, Scope::Upper::SCOPE(1));
1065
1066     $class->setup_finalize;
1067 }
1068
1069
1070 =head2 $app->setup_finalize
1071
1072 A hook to attach modifiers to.
1073 Using C< after setup => sub{}; > doesn't work, because of quirky things done for plugin setup.
1074 Also better than C< setup_finished(); >, as that is a getter method.
1075
1076     sub setup_finalize {
1077
1078         my $app = shift;
1079
1080         ## do stuff, i.e., determine a primary key column for sessions stored in a DB
1081
1082         $app->next::method(@_);
1083
1084
1085     }
1086
1087 =cut
1088
1089 sub setup_finalize {
1090     my ($class) = @_;
1091     $class->setup_finished(1);
1092 }
1093
1094 =head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
1095
1096 =head2 $c->uri_for( $path, @args?, \%query_values? )
1097
1098 =over
1099
1100 =item $action
1101
1102 A Catalyst::Action object representing the Catalyst action you want to
1103 create a URI for. To get one for an action in the current controller,
1104 use C<< $c->action('someactionname') >>. To get one from different
1105 controller, fetch the controller using C<< $c->controller() >>, then
1106 call C<action_for> on it.
1107
1108 You can maintain the arguments captured by an action (e.g.: Regex, Chained)
1109 using C<< $c->req->captures >>. 
1110
1111   # For the current action
1112   $c->uri_for($c->action, $c->req->captures);
1113   
1114   # For the Foo action in the Bar controller
1115   $c->uri_for($c->controller->('Bar')->action_for('Foo'), $c->req->captures);
1116
1117 =back
1118
1119 =cut
1120
1121 sub uri_for {
1122     my ( $c, $path, @args ) = @_;
1123
1124     if ( blessed($path) ) { # action object
1125         my $captures = ( scalar @args && ref $args[0] eq 'ARRAY'
1126                          ? shift(@args)
1127                          : [] );
1128         $path = $c->dispatcher->uri_for_action($path, $captures);
1129         return undef unless defined($path);
1130         $path = '/' if $path eq '';
1131     }
1132
1133     undef($path) if (defined $path && $path eq '');
1134
1135     my $params =
1136       ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
1137
1138     carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
1139     s/([^$URI::uric])/$URI::Escape::escapes{$1}/go for @args;
1140
1141     unshift(@args, $path);
1142
1143     unless (defined $path && $path =~ s!^/!!) { # in-place strip
1144         my $namespace = $c->namespace;
1145         if (defined $path) { # cheesy hack to handle path '../foo'
1146            $namespace =~ s{(?:^|/)[^/]+$}{} while $args[0] =~ s{^\.\./}{};
1147         }
1148         unshift(@args, $namespace || '');
1149     }
1150     
1151     # join args with '/', or a blank string
1152     my $args = join('/', grep { defined($_) } @args);
1153     $args =~ s/\?/%3F/g; # STUPID STUPID SPECIAL CASE
1154     $args =~ s!^/+!!;
1155     my $base = $c->req->base;
1156     my $class = ref($base);
1157     $base =~ s{(?<!/)$}{/};
1158
1159     my $query = '';
1160
1161     if (my @keys = keys %$params) {
1162       # somewhat lifted from URI::_query's query_form
1163       $query = '?'.join('&', map {
1164           my $val = $params->{$_};
1165           s/([;\/?:@&=+,\$\[\]%])/$URI::Escape::escapes{$1}/go;
1166           s/ /+/g;
1167           my $key = $_;
1168           $val = '' unless defined $val;
1169           (map {
1170               $_ = "$_";
1171               utf8::encode( $_ ) if utf8::is_utf8($_);
1172               # using the URI::Escape pattern here so utf8 chars survive
1173               s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
1174               s/ /+/g;
1175               "${key}=$_"; } ( ref $val eq 'ARRAY' ? @$val : $val ));
1176       } @keys);
1177     }
1178
1179     my $res = bless(\"${base}${args}${query}", $class);
1180     $res;
1181 }
1182
1183 =head2 $c->welcome_message
1184
1185 Returns the Catalyst welcome HTML page.
1186
1187 =cut
1188
1189 sub welcome_message {
1190     my $c      = shift;
1191     my $name   = $c->config->{name};
1192     my $logo   = $c->uri_for('/static/images/catalyst_logo.png');
1193     my $prefix = Catalyst::Utils::appprefix( ref $c );
1194     $c->response->content_type('text/html; charset=utf-8');
1195     return <<"EOF";
1196 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1197     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1198 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
1199     <head>
1200     <meta http-equiv="Content-Language" content="en" />
1201     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1202         <title>$name on Catalyst $VERSION</title>
1203         <style type="text/css">
1204             body {
1205                 color: #000;
1206                 background-color: #eee;
1207             }
1208             div#content {
1209                 width: 640px;
1210                 margin-left: auto;
1211                 margin-right: auto;
1212                 margin-top: 10px;
1213                 margin-bottom: 10px;
1214                 text-align: left;
1215                 background-color: #ccc;
1216                 border: 1px solid #aaa;
1217             }
1218             p, h1, h2 {
1219                 margin-left: 20px;
1220                 margin-right: 20px;
1221                 font-family: verdana, tahoma, sans-serif;
1222             }
1223             a {
1224                 font-family: verdana, tahoma, sans-serif;
1225             }
1226             :link, :visited {
1227                     text-decoration: none;
1228                     color: #b00;
1229                     border-bottom: 1px dotted #bbb;
1230             }
1231             :link:hover, :visited:hover {
1232                     color: #555;
1233             }
1234             div#topbar {
1235                 margin: 0px;
1236             }
1237             pre {
1238                 margin: 10px;
1239                 padding: 8px;
1240             }
1241             div#answers {
1242                 padding: 8px;
1243                 margin: 10px;
1244                 background-color: #fff;
1245                 border: 1px solid #aaa;
1246             }
1247             h1 {
1248                 font-size: 0.9em;
1249                 font-weight: normal;
1250                 text-align: center;
1251             }
1252             h2 {
1253                 font-size: 1.0em;
1254             }
1255             p {
1256                 font-size: 0.9em;
1257             }
1258             p img {
1259                 float: right;
1260                 margin-left: 10px;
1261             }
1262             span#appname {
1263                 font-weight: bold;
1264                 font-size: 1.6em;
1265             }
1266         </style>
1267     </head>
1268     <body>
1269         <div id="content">
1270             <div id="topbar">
1271                 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
1272                     $VERSION</h1>
1273              </div>
1274              <div id="answers">
1275                  <p>
1276                  <img src="$logo" alt="Catalyst Logo" />
1277                  </p>
1278                  <p>Welcome to the  world of Catalyst.
1279                     This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
1280                     framework will make web development something you had
1281                     never expected it to be: Fun, rewarding, and quick.</p>
1282                  <h2>What to do now?</h2>
1283                  <p>That really depends  on what <b>you</b> want to do.
1284                     We do, however, provide you with a few starting points.</p>
1285                  <p>If you want to jump right into web development with Catalyst
1286                     you might want to start with a tutorial.</p>
1287 <pre>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
1288 </pre>
1289 <p>Afterwards you can go on to check out a more complete look at our features.</p>
1290 <pre>
1291 <code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
1292 <!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
1293 </code></pre>
1294                  <h2>What to do next?</h2>
1295                  <p>Next it's time to write an actual application. Use the
1296                     helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&amp;mode=all">controllers</a>,
1297                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&amp;mode=all">models</a>, and
1298                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&amp;mode=all">views</a>;
1299                     they can save you a lot of work.</p>
1300                     <pre><code>script/${prefix}_create.pl -help</code></pre>
1301                     <p>Also, be sure to check out the vast and growing
1302                     collection of <a href="http://search.cpan.org/search?query=Catalyst">plugins for Catalyst on CPAN</a>;
1303                     you are likely to find what you need there.
1304                     </p>
1305
1306                  <h2>Need help?</h2>
1307                  <p>Catalyst has a very active community. Here are the main places to
1308                     get in touch with us.</p>
1309                  <ul>
1310                      <li>
1311                          <a href="http://dev.catalyst.perl.org">Wiki</a>
1312                      </li>
1313                      <li>
1314                          <a href="http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst">Mailing-List</a>
1315                      </li>
1316                      <li>
1317                          <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
1318                      </li>
1319                  </ul>
1320                  <h2>In conclusion</h2>
1321                  <p>The Catalyst team hopes you will enjoy using Catalyst as much 
1322                     as we enjoyed making it. Please contact us if you have ideas
1323                     for improvement or other feedback.</p>
1324              </div>
1325          </div>
1326     </body>
1327 </html>
1328 EOF
1329 }
1330
1331 =head1 INTERNAL METHODS
1332
1333 These methods are not meant to be used by end users.
1334
1335 =head2 $c->components
1336
1337 Returns a hash of components.
1338
1339 =head2 $c->context_class
1340
1341 Returns or sets the context class.
1342
1343 =head2 $c->counter
1344
1345 Returns a hashref containing coderefs and execution counts (needed for
1346 deep recursion detection).
1347
1348 =head2 $c->depth
1349
1350 Returns the number of actions on the current internal execution stack.
1351
1352 =head2 $c->dispatch
1353
1354 Dispatches a request to actions.
1355
1356 =cut
1357
1358 sub dispatch { my $c = shift; $c->dispatcher->dispatch( $c, @_ ) }
1359
1360 =head2 $c->dispatcher_class
1361
1362 Returns or sets the dispatcher class.
1363
1364 =head2 $c->dump_these
1365
1366 Returns a list of 2-element array references (name, structure) pairs
1367 that will be dumped on the error page in debug mode.
1368
1369 =cut
1370
1371 sub dump_these {
1372     my $c = shift;
1373     [ Request => $c->req ], 
1374     [ Response => $c->res ], 
1375     [ Stash => $c->stash ],
1376     [ Config => $c->config ];
1377 }
1378
1379 =head2 $c->engine_class
1380
1381 Returns or sets the engine class.
1382
1383 =head2 $c->execute( $class, $coderef )
1384
1385 Execute a coderef in given class and catch exceptions. Errors are available
1386 via $c->error.
1387
1388 =cut
1389
1390 sub execute {
1391     my ( $c, $class, $code ) = @_;
1392     $class = $c->component($class) || $class;
1393     $c->state(0);
1394
1395     if ( $c->depth >= $RECURSION ) {
1396         my $action = $code->reverse();
1397         $action = "/$action" unless $action =~ /->/;
1398         my $error = qq/Deep recursion detected calling "${action}"/;
1399         $c->log->error($error);
1400         $c->error($error);
1401         $c->state(0);
1402         return $c->state;
1403     }
1404
1405     my $stats_info = $c->_stats_start_execute( $code ) if $c->use_stats;
1406
1407     push( @{ $c->stack }, $code );
1408     
1409     eval { $c->state( $code->execute( $class, $c, @{ $c->req->args } ) || 0 ) };
1410
1411     $c->_stats_finish_execute( $stats_info ) if $c->use_stats and $stats_info;
1412     
1413     my $last = pop( @{ $c->stack } );
1414
1415     if ( my $error = $@ ) {
1416         if ( !ref($error) and $error eq $DETACH ) {
1417             die $DETACH if($c->depth > 1);
1418         }
1419         elsif ( !ref($error) and $error eq $GO ) {
1420             die $GO if($c->depth > 0);
1421         }
1422         else {
1423             unless ( ref $error ) {
1424                 no warnings 'uninitialized';
1425                 chomp $error;
1426                 my $class = $last->class;
1427                 my $name  = $last->name;
1428                 $error = qq/Caught exception in $class->$name "$error"/;
1429             }
1430             $c->error($error);
1431             $c->state(0);
1432         }
1433     }
1434     return $c->state;
1435 }
1436
1437 sub _stats_start_execute {
1438     my ( $c, $code ) = @_;
1439
1440     return if ( ( $code->name =~ /^_.*/ )
1441         && ( !$c->config->{show_internal_actions} ) );
1442
1443     my $action_name = $code->reverse();
1444     $c->counter->{$action_name}++;
1445
1446     my $action = $action_name;
1447     $action = "/$action" unless $action =~ /->/;
1448
1449     # determine if the call was the result of a forward
1450     # this is done by walking up the call stack and looking for a calling
1451     # sub of Catalyst::forward before the eval
1452     my $callsub = q{};
1453     for my $index ( 2 .. 11 ) {
1454         last
1455         if ( ( caller($index) )[0] eq 'Catalyst'
1456             && ( caller($index) )[3] eq '(eval)' );
1457
1458         if ( ( caller($index) )[3] =~ /forward$/ ) {
1459             $callsub = ( caller($index) )[3];
1460             $action  = "-> $action";
1461             last;
1462         }
1463     }
1464
1465     my $uid = $action_name . $c->counter->{$action_name};
1466
1467     # is this a root-level call or a forwarded call?
1468     if ( $callsub =~ /forward$/ ) {
1469
1470         # forward, locate the caller
1471         if ( my $parent = $c->stack->[-1] ) {
1472             $c->stats->profile(
1473                 begin  => $action, 
1474                 parent => "$parent" . $c->counter->{"$parent"},
1475                 uid    => $uid,
1476             );
1477         }
1478         else {
1479
1480             # forward with no caller may come from a plugin
1481             $c->stats->profile(
1482                 begin => $action,
1483                 uid   => $uid,
1484             );
1485         }
1486     }
1487     else {
1488         
1489         # root-level call
1490         $c->stats->profile(
1491             begin => $action,
1492             uid   => $uid,
1493         );
1494     }
1495     return $action;
1496
1497 }
1498
1499 sub _stats_finish_execute {
1500     my ( $c, $info ) = @_;
1501     $c->stats->profile( end => $info );
1502 }
1503
1504 =head2 $c->_localize_fields( sub { }, \%keys );
1505
1506 =cut
1507
1508 #Why does this exist? This is no longer safe and WILL NOT WORK.
1509 # it doesnt seem to be used anywhere. can we remove it?
1510 sub _localize_fields {
1511     my ( $c, $localized, $code ) = ( @_ );
1512
1513     my $request = delete $localized->{request} || {};
1514     my $response = delete $localized->{response} || {};
1515     
1516     local @{ $c }{ keys %$localized } = values %$localized;
1517     local @{ $c->request }{ keys %$request } = values %$request;
1518     local @{ $c->response }{ keys %$response } = values %$response;
1519
1520     $code->();
1521 }
1522
1523 =head2 $c->finalize
1524
1525 Finalizes the request.
1526
1527 =cut
1528
1529 sub finalize {
1530     my $c = shift;
1531
1532     for my $error ( @{ $c->error } ) {
1533         $c->log->error($error);
1534     }
1535
1536     # Allow engine to handle finalize flow (for POE)
1537     my $engine = $c->engine;
1538     if ( my $code = $engine->can('finalize') ) {
1539         $engine->$code($c);
1540     }
1541     else {
1542
1543         $c->finalize_uploads;
1544
1545         # Error
1546         if ( $#{ $c->error } >= 0 ) {
1547             $c->finalize_error;
1548         }
1549
1550         $c->finalize_headers;
1551
1552         # HEAD request
1553         if ( $c->request->method eq 'HEAD' ) {
1554             $c->response->body('');
1555         }
1556
1557         $c->finalize_body;
1558     }
1559     
1560     if ($c->use_stats) {        
1561         my $elapsed = sprintf '%f', $c->stats->elapsed;
1562         my $av = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed;
1563         $c->log->info(
1564             "Request took ${elapsed}s ($av/s)\n" . $c->stats->report . "\n" );        
1565     }
1566
1567     return $c->response->status;
1568 }
1569
1570 =head2 $c->finalize_body
1571
1572 Finalizes body.
1573
1574 =cut
1575
1576 sub finalize_body { my $c = shift; $c->engine->finalize_body( $c, @_ ) }
1577
1578 =head2 $c->finalize_cookies
1579
1580 Finalizes cookies.
1581
1582 =cut
1583
1584 sub finalize_cookies { my $c = shift; $c->engine->finalize_cookies( $c, @_ ) }
1585
1586 =head2 $c->finalize_error
1587
1588 Finalizes error.
1589
1590 =cut
1591
1592 sub finalize_error { my $c = shift; $c->engine->finalize_error( $c, @_ ) }
1593
1594 =head2 $c->finalize_headers
1595
1596 Finalizes headers.
1597
1598 =cut
1599
1600 sub finalize_headers {
1601     my $c = shift;
1602
1603     my $response = $c->response; #accessor calls can add up?
1604
1605     # Check if we already finalized headers
1606     return if $response->finalized_headers;
1607
1608     # Handle redirects
1609     if ( my $location = $response->redirect ) {
1610         $c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
1611         $response->header( Location => $location );
1612
1613         if ( !$response->has_body ) {
1614             # Add a default body if none is already present
1615             $response->body(
1616                 qq{<html><body><p>This item has moved <a href="$location">here</a>.</p></body></html>}
1617             );
1618         }
1619     }
1620
1621     # Content-Length
1622     if ( $response->body && !$response->content_length ) {
1623
1624         # get the length from a filehandle
1625         if ( blessed( $response->body ) && $response->body->can('read') )
1626         {
1627             my $stat = stat $response->body;
1628             if ( $stat && $stat->size > 0 ) {
1629                 $response->content_length( $stat->size );
1630             }
1631             else {
1632                 $c->log->warn('Serving filehandle without a content-length');
1633             }
1634         }
1635         else {
1636             # everything should be bytes at this point, but just in case
1637             $response->content_length( bytes::length( $response->body ) );
1638         }
1639     }
1640
1641     # Errors
1642     if ( $response->status =~ /^(1\d\d|[23]04)$/ ) {
1643         $response->headers->remove_header("Content-Length");
1644         $response->body('');
1645     }
1646
1647     $c->finalize_cookies;
1648
1649     $c->engine->finalize_headers( $c, @_ );
1650
1651     # Done
1652     $response->finalized_headers(1);
1653 }
1654
1655 =head2 $c->finalize_output
1656
1657 An alias for finalize_body.
1658
1659 =head2 $c->finalize_read
1660
1661 Finalizes the input after reading is complete.
1662
1663 =cut
1664
1665 sub finalize_read { my $c = shift; $c->engine->finalize_read( $c, @_ ) }
1666
1667 =head2 $c->finalize_uploads
1668
1669 Finalizes uploads. Cleans up any temporary files.
1670
1671 =cut
1672
1673 sub finalize_uploads { my $c = shift; $c->engine->finalize_uploads( $c, @_ ) }
1674
1675 =head2 $c->get_action( $action, $namespace )
1676
1677 Gets an action in a given namespace.
1678
1679 =cut
1680
1681 sub get_action { my $c = shift; $c->dispatcher->get_action(@_) }
1682
1683 =head2 $c->get_actions( $action, $namespace )
1684
1685 Gets all actions of a given name in a namespace and all parent
1686 namespaces.
1687
1688 =cut
1689
1690 sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) }
1691
1692 =head2 $c->handle_request( $class, @arguments )
1693
1694 Called to handle each HTTP request.
1695
1696 =cut
1697
1698 sub handle_request {
1699     my ( $class, @arguments ) = @_;
1700
1701     # Always expect worst case!
1702     my $status = -1;
1703     eval {
1704         if ($class->debug) {
1705             my $secs = time - $START || 1;
1706             my $av = sprintf '%.3f', $COUNT / $secs;
1707             my $time = localtime time;
1708             $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
1709         }
1710
1711         my $c = $class->prepare(@arguments);
1712         $c->dispatch;
1713         $status = $c->finalize;   
1714     };
1715
1716     if ( my $error = $@ ) {
1717         chomp $error;
1718         $class->log->error(qq/Caught exception in engine "$error"/);
1719     }
1720
1721     $COUNT++;
1722     
1723     if(my $coderef = $class->log->can('_flush')){
1724         $class->log->$coderef();
1725     }
1726     return $status;
1727 }
1728
1729 =head2 $c->prepare( @arguments )
1730
1731 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1732 etc.).
1733
1734 =cut
1735
1736 sub prepare {
1737     my ( $class, @arguments ) = @_;
1738
1739     # XXX
1740     # After the app/ctxt split, this should become an attribute based on something passed
1741     # into the application.
1742     $class->context_class( ref $class || $class ) unless $class->context_class;
1743    
1744     my $c = $class->context_class->new({});
1745
1746     # For on-demand data
1747     $c->request->_context($c);
1748     $c->response->_context($c);
1749
1750     #surely this is not the most efficient way to do things...
1751     $c->stats($class->stats_class->new)->enable($c->use_stats);
1752     if ( $c->debug ) {
1753         $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );            
1754     }
1755
1756     #XXX reuse coderef from can
1757     # Allow engine to direct the prepare flow (for POE)
1758     if ( $c->engine->can('prepare') ) {
1759         $c->engine->prepare( $c, @arguments );
1760     }
1761     else {
1762         $c->prepare_request(@arguments);
1763         $c->prepare_connection;
1764         $c->prepare_query_parameters;
1765         $c->prepare_headers;
1766         $c->prepare_cookies;
1767         $c->prepare_path;
1768
1769         # Prepare the body for reading, either by prepare_body
1770         # or the user, if they are using $c->read
1771         $c->prepare_read;
1772         
1773         # Parse the body unless the user wants it on-demand
1774         unless ( $c->config->{parse_on_demand} ) {
1775             $c->prepare_body;
1776         }
1777     }
1778
1779     my $method  = $c->req->method  || '';
1780     my $path    = $c->req->path;
1781     $path       = '/' unless length $path;
1782     my $address = $c->req->address || '';
1783
1784     $c->log->debug(qq/"$method" request for "$path" from "$address"/)
1785       if $c->debug;
1786
1787     $c->prepare_action;
1788
1789     return $c;
1790 }
1791
1792 =head2 $c->prepare_action
1793
1794 Prepares action. See L<Catalyst::Dispatcher>.
1795
1796 =cut
1797
1798 sub prepare_action { my $c = shift; $c->dispatcher->prepare_action( $c, @_ ) }
1799
1800 =head2 $c->prepare_body
1801
1802 Prepares message body.
1803
1804 =cut
1805
1806 sub prepare_body {
1807     my $c = shift;
1808
1809     return if $c->request->_has_body;
1810
1811     # Initialize on-demand data
1812     $c->engine->prepare_body( $c, @_ );
1813     $c->prepare_parameters;
1814     $c->prepare_uploads;
1815
1816     if ( $c->debug && keys %{ $c->req->body_parameters } ) {
1817         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1818         for my $key ( sort keys %{ $c->req->body_parameters } ) {
1819             my $param = $c->req->body_parameters->{$key};
1820             my $value = defined($param) ? $param : '';
1821             $t->row( $key,
1822                 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1823         }
1824         $c->log->debug( "Body Parameters are:\n" . $t->draw );
1825     }
1826 }
1827
1828 =head2 $c->prepare_body_chunk( $chunk )
1829
1830 Prepares a chunk of data before sending it to L<HTTP::Body>.
1831
1832 See L<Catalyst::Engine>.
1833
1834 =cut
1835
1836 sub prepare_body_chunk {
1837     my $c = shift;
1838     $c->engine->prepare_body_chunk( $c, @_ );
1839 }
1840
1841 =head2 $c->prepare_body_parameters
1842
1843 Prepares body parameters.
1844
1845 =cut
1846
1847 sub prepare_body_parameters {
1848     my $c = shift;
1849     $c->engine->prepare_body_parameters( $c, @_ );
1850 }
1851
1852 =head2 $c->prepare_connection
1853
1854 Prepares connection.
1855
1856 =cut
1857
1858 sub prepare_connection {
1859     my $c = shift;
1860     $c->engine->prepare_connection( $c, @_ );
1861 }
1862
1863 =head2 $c->prepare_cookies
1864
1865 Prepares cookies.
1866
1867 =cut
1868
1869 sub prepare_cookies { my $c = shift; $c->engine->prepare_cookies( $c, @_ ) }
1870
1871 =head2 $c->prepare_headers
1872
1873 Prepares headers.
1874
1875 =cut
1876
1877 sub prepare_headers { my $c = shift; $c->engine->prepare_headers( $c, @_ ) }
1878
1879 =head2 $c->prepare_parameters
1880
1881 Prepares parameters.
1882
1883 =cut
1884
1885 sub prepare_parameters {
1886     my $c = shift;
1887     $c->prepare_body_parameters;
1888     $c->engine->prepare_parameters( $c, @_ );
1889 }
1890
1891 =head2 $c->prepare_path
1892
1893 Prepares path and base.
1894
1895 =cut
1896
1897 sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) }
1898
1899 =head2 $c->prepare_query_parameters
1900
1901 Prepares query parameters.
1902
1903 =cut
1904
1905 sub prepare_query_parameters {
1906     my $c = shift;
1907
1908     $c->engine->prepare_query_parameters( $c, @_ );
1909
1910     if ( $c->debug && keys %{ $c->request->query_parameters } ) {
1911         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1912         for my $key ( sort keys %{ $c->req->query_parameters } ) {
1913             my $param = $c->req->query_parameters->{$key};
1914             my $value = defined($param) ? $param : '';
1915             $t->row( $key,
1916                 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1917         }
1918         $c->log->debug( "Query Parameters are:\n" . $t->draw );
1919     }
1920 }
1921
1922 =head2 $c->prepare_read
1923
1924 Prepares the input for reading.
1925
1926 =cut
1927
1928 sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
1929
1930 =head2 $c->prepare_request
1931
1932 Prepares the engine request.
1933
1934 =cut
1935
1936 sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
1937
1938 =head2 $c->prepare_uploads
1939
1940 Prepares uploads.
1941
1942 =cut
1943
1944 sub prepare_uploads {
1945     my $c = shift;
1946
1947     $c->engine->prepare_uploads( $c, @_ );
1948
1949     if ( $c->debug && keys %{ $c->request->uploads } ) {
1950         my $t = Text::SimpleTable->new(
1951             [ 12, 'Parameter' ],
1952             [ 26, 'Filename' ],
1953             [ 18, 'Type' ],
1954             [ 9,  'Size' ]
1955         );
1956         for my $key ( sort keys %{ $c->request->uploads } ) {
1957             my $upload = $c->request->uploads->{$key};
1958             for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
1959                 $t->row( $key, $u->filename, $u->type, $u->size );
1960             }
1961         }
1962         $c->log->debug( "File Uploads are:\n" . $t->draw );
1963     }
1964 }
1965
1966 =head2 $c->prepare_write
1967
1968 Prepares the output for writing.
1969
1970 =cut
1971
1972 sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
1973
1974 =head2 $c->request_class
1975
1976 Returns or sets the request class.
1977
1978 =head2 $c->response_class
1979
1980 Returns or sets the response class.
1981
1982 =head2 $c->read( [$maxlength] )
1983
1984 Reads a chunk of data from the request body. This method is designed to
1985 be used in a while loop, reading C<$maxlength> bytes on every call.
1986 C<$maxlength> defaults to the size of the request if not specified.
1987
1988 You have to set C<< MyApp->config->{parse_on_demand} >> to use this
1989 directly.
1990
1991 Warning: If you use read(), Catalyst will not process the body,
1992 so you will not be able to access POST parameters or file uploads via
1993 $c->request.  You must handle all body parsing yourself.
1994
1995 =cut
1996
1997 sub read { my $c = shift; return $c->engine->read( $c, @_ ) }
1998
1999 =head2 $c->run
2000
2001 Starts the engine.
2002
2003 =cut
2004
2005 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
2006
2007 =head2 $c->set_action( $action, $code, $namespace, $attrs )
2008
2009 Sets an action in a given namespace.
2010
2011 =cut
2012
2013 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
2014
2015 =head2 $c->setup_actions($component)
2016
2017 Sets up actions for a component.
2018
2019 =cut
2020
2021 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
2022
2023 =head2 $c->setup_components
2024
2025 Sets up components. Specify a C<setup_components> config option to pass
2026 additional options directly to L<Module::Pluggable>. To add additional
2027 search paths, specify a key named C<search_extra> as an array
2028 reference. Items in the array beginning with C<::> will have the
2029 application class name prepended to them.
2030
2031 All components found will also have any 
2032 L<Devel::InnerPackage|inner packages> loaded and set up as components.
2033 Note, that modules which are B<not> an I<inner package> of the main
2034 file namespace loaded will not be instantiated as components.
2035
2036 =cut
2037
2038 sub setup_components {
2039     my $class = shift;
2040
2041     my @paths   = qw( ::Controller ::C ::Model ::M ::View ::V );
2042     my $config  = $class->config->{ setup_components };
2043     my $extra   = delete $config->{ search_extra } || [];
2044     
2045     push @paths, @$extra;
2046         
2047     my $locator = Module::Pluggable::Object->new(
2048         search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
2049         %$config
2050     );
2051
2052     my @comps = sort { length $a <=> length $b } $locator->plugins;
2053     my %comps = map { $_ => 1 } @comps;
2054
2055     my $deprecated_component_names = grep { /::[CMV]::/ } @comps;
2056     $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
2057         qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
2058     ) if $deprecated_component_names;
2059
2060     for my $component ( @comps ) {
2061
2062         # We pass ignore_loaded here so that overlay files for (e.g.)
2063         # Model::DBI::Schema sub-classes are loaded - if it's in @comps
2064         # we know M::P::O found a file on disk so this is safe
2065
2066         Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
2067         #Class::MOP::load_class($component);
2068
2069         my $module  = $class->setup_component( $component );
2070         my %modules = (
2071             $component => $module,
2072             map {
2073                 $_ => $class->setup_component( $_ )
2074             } grep { 
2075               not exists $comps{$_}
2076             } Devel::InnerPackage::list_packages( $component )
2077         );
2078         
2079         for my $key ( keys %modules ) {
2080             $class->components->{ $key } = $modules{ $key };
2081         }
2082     }
2083 }
2084
2085 =head2 $c->setup_component
2086
2087 =cut
2088
2089 sub setup_component {
2090     my( $class, $component ) = @_;
2091
2092     unless ( $component->can( 'COMPONENT' ) ) {
2093         return $component;
2094     }
2095
2096     my $suffix = Catalyst::Utils::class2classsuffix( $component );
2097     my $config = $class->config->{ $suffix } || {};
2098
2099     my $instance = eval { $component->COMPONENT( $class, $config ); };
2100
2101     if ( my $error = $@ ) {
2102         chomp $error;
2103         Catalyst::Exception->throw(
2104             message => qq/Couldn't instantiate component "$component", "$error"/
2105         );
2106     }
2107
2108     Catalyst::Exception->throw(
2109         message =>
2110         qq/Couldn't instantiate component "$component", "COMPONENT() didn't return an object-like value"/
2111     ) unless blessed($instance);
2112
2113     return $instance;
2114 }
2115
2116 =head2 $c->setup_dispatcher
2117
2118 Sets up dispatcher.
2119
2120 =cut
2121
2122 sub setup_dispatcher {
2123     my ( $class, $dispatcher ) = @_;
2124
2125     if ($dispatcher) {
2126         $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
2127     }
2128
2129     if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
2130         $dispatcher = 'Catalyst::Dispatcher::' . $env;
2131     }
2132
2133     unless ($dispatcher) {
2134         $dispatcher = $class->dispatcher_class;
2135     }
2136
2137     Class::MOP::load_class($dispatcher);
2138
2139     # dispatcher instance
2140     $class->dispatcher( $dispatcher->new );
2141 }
2142
2143 =head2 $c->setup_engine
2144
2145 Sets up engine.
2146
2147 =cut
2148
2149 sub setup_engine {
2150     my ( $class, $engine ) = @_;
2151
2152     if ($engine) {
2153         $engine = 'Catalyst::Engine::' . $engine;
2154     }
2155
2156     if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
2157         $engine = 'Catalyst::Engine::' . $env;
2158     }
2159
2160     if ( $ENV{MOD_PERL} ) {
2161         my $meta = Class::MOP::get_metaclass_by_name($class);
2162         
2163         # create the apache method
2164         $meta->add_method('apache' => sub { shift->engine->apache });
2165
2166         my ( $software, $version ) =
2167           $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
2168
2169         $version =~ s/_//g;
2170         $version =~ s/(\.[^.]+)\./$1/g;
2171
2172         if ( $software eq 'mod_perl' ) {
2173
2174             if ( !$engine ) {
2175
2176                 if ( $version >= 1.99922 ) {
2177                     $engine = 'Catalyst::Engine::Apache2::MP20';
2178                 }
2179
2180                 elsif ( $version >= 1.9901 ) {
2181                     $engine = 'Catalyst::Engine::Apache2::MP19';
2182                 }
2183
2184                 elsif ( $version >= 1.24 ) {
2185                     $engine = 'Catalyst::Engine::Apache::MP13';
2186                 }
2187
2188                 else {
2189                     Catalyst::Exception->throw( message =>
2190                           qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
2191                 }
2192
2193             }
2194
2195             # install the correct mod_perl handler
2196             if ( $version >= 1.9901 ) {
2197                 *handler = sub  : method {
2198                     shift->handle_request(@_);
2199                 };
2200             }
2201             else {
2202                 *handler = sub ($$) { shift->handle_request(@_) };
2203             }
2204
2205         }
2206
2207         elsif ( $software eq 'Zeus-Perl' ) {
2208             $engine = 'Catalyst::Engine::Zeus';
2209         }
2210
2211         else {
2212             Catalyst::Exception->throw(
2213                 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
2214         }
2215     }
2216
2217     unless ($engine) {
2218         $engine = $class->engine_class;
2219     }
2220
2221     Class::MOP::load_class($engine);
2222
2223     # check for old engines that are no longer compatible
2224     my $old_engine;
2225     if ( $engine->isa('Catalyst::Engine::Apache')
2226         && !Catalyst::Engine::Apache->VERSION )
2227     {
2228         $old_engine = 1;
2229     }
2230
2231     elsif ( $engine->isa('Catalyst::Engine::Server::Base')
2232         && Catalyst::Engine::Server->VERSION le '0.02' )
2233     {
2234         $old_engine = 1;
2235     }
2236
2237     elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
2238         && $engine->VERSION eq '0.01' )
2239     {
2240         $old_engine = 1;
2241     }
2242
2243     elsif ($engine->isa('Catalyst::Engine::Zeus')
2244         && $engine->VERSION eq '0.01' )
2245     {
2246         $old_engine = 1;
2247     }
2248
2249     if ($old_engine) {
2250         Catalyst::Exception->throw( message =>
2251               qq/Engine "$engine" is not supported by this version of Catalyst/
2252         );
2253     }
2254
2255     # engine instance
2256     $class->engine( $engine->new );
2257 }
2258
2259 =head2 $c->setup_home
2260
2261 Sets up the home directory.
2262
2263 =cut
2264
2265 sub setup_home {
2266     my ( $class, $home ) = @_;
2267
2268     if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
2269         $home = $env;
2270     }
2271
2272     $home ||= Catalyst::Utils::home($class);
2273
2274     if ($home) {
2275         #I remember recently being scolded for assigning config values like this
2276         $class->config->{home} ||= $home;
2277         $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
2278     }
2279 }
2280
2281 =head2 $c->setup_log
2282
2283 Sets up log by instantiating a L<Catalyst::Log|Catalyst::Log> object and
2284 passing it to C<log()>. Pass in a comma-delimited list of levels to set the
2285 log to.
2286  
2287 This method also installs a C<debug> method that returns a true value into the
2288 catalyst subclass if the "debug" level is passed in the comma-delimited list,
2289 or if the C<$CATALYST_DEBUG> environment variable is set to a true value.
2290
2291 Note that if the log has already been setup, by either a previous call to
2292 C<setup_log> or by a call such as C<< __PACKAGE__->log( MyLogger->new ) >>,
2293 that this method won't actually set up the log object.
2294
2295 =cut
2296
2297 sub setup_log {
2298     my ( $class, $levels ) = @_;
2299
2300     $levels ||= '';
2301     $levels =~ s/^\s+//;
2302     $levels =~ s/\s+$//;
2303     my %levels = map { $_ => 1 } split /\s*,\s*/, $levels || '';
2304     
2305     unless ( $class->log ) {
2306         $class->log( Catalyst::Log->new(keys %levels) );
2307     }
2308
2309     my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
2310     if ( defined($env_debug) or $levels{debug} ) {
2311         Class::MOP::get_metaclass_by_name($class)->add_method('debug' => sub { 1 });
2312         $class->log->debug('Debug messages enabled');
2313     }
2314 }
2315
2316 =head2 $c->setup_plugins
2317
2318 Sets up plugins.
2319
2320 =cut
2321
2322 =head2 $c->setup_stats
2323
2324 Sets up timing statistics class.
2325
2326 =cut
2327
2328 sub setup_stats {
2329     my ( $class, $stats ) = @_;
2330
2331     Catalyst::Utils::ensure_class_loaded($class->stats_class);
2332
2333     my $env = Catalyst::Utils::env_value( $class, 'STATS' );
2334     if ( defined($env) ? $env : ($stats || $class->debug ) ) {
2335         Class::MOP::get_metaclass_by_name($class)->add_method('use_stats' => sub { 1 });
2336         $class->log->debug('Statistics enabled');
2337     }
2338 }
2339
2340
2341 =head2 $c->registered_plugins 
2342
2343 Returns a sorted list of the plugins which have either been stated in the
2344 import list or which have been added via C<< MyApp->plugin(@args); >>.
2345
2346 If passed a given plugin name, it will report a boolean value indicating
2347 whether or not that plugin is loaded.  A fully qualified name is required if
2348 the plugin name does not begin with C<Catalyst::Plugin::>.
2349
2350  if ($c->registered_plugins('Some::Plugin')) {
2351      ...
2352  }
2353
2354 =cut
2355
2356 {
2357
2358     sub registered_plugins {
2359         my $proto = shift;
2360         return sort keys %{ $proto->_plugins } unless @_;
2361         my $plugin = shift;
2362         return 1 if exists $proto->_plugins->{$plugin};
2363         return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
2364     }
2365
2366     sub _register_plugin {
2367         my ( $proto, $plugin, $instant ) = @_;
2368         my $class = ref $proto || $proto;
2369
2370         # no ignore_loaded here, the plugin may already have been
2371         # defined in memory and we don't want to error on "no file" if so
2372
2373         Class::MOP::load_class( $plugin );
2374
2375         $proto->_plugins->{$plugin} = 1;
2376         unless ($instant) {
2377             no strict 'refs';
2378             if ( my $meta = Class::MOP::get_metaclass_by_name($class) ) {
2379               my @superclasses = ($plugin, $meta->superclasses );
2380               $meta->superclasses(@superclasses);
2381             } else {
2382               unshift @{"$class\::ISA"}, $plugin;
2383             }
2384         }
2385         return $class;
2386     }
2387
2388     sub setup_plugins {
2389         my ( $class, $plugins ) = @_;
2390
2391         $class->_plugins( {} ) unless $class->_plugins;
2392         $plugins ||= [];
2393         for my $plugin ( reverse @$plugins ) {
2394
2395             unless ( $plugin =~ s/\A\+// ) {
2396                 $plugin = "Catalyst::Plugin::$plugin";
2397             }
2398
2399             $class->_register_plugin($plugin);
2400         }
2401     }
2402 }
2403
2404 =head2 $c->stack
2405
2406 Returns an arrayref of the internal execution stack (actions that are
2407 currently executing).
2408
2409 =head2 $c->stats_class
2410
2411 Returns or sets the stats (timing statistics) class.
2412
2413 =head2 $c->use_stats
2414
2415 Returns 1 when stats collection is enabled.  Stats collection is enabled
2416 when the -Stats options is set, debug is on or when the <MYAPP>_STATS
2417 environment variable is set.
2418
2419 Note that this is a static method, not an accessor and should be overloaded
2420 by declaring "sub use_stats { 1 }" in your MyApp.pm, not by calling $c->use_stats(1).
2421
2422 =cut
2423
2424 sub use_stats { 0 }
2425
2426
2427 =head2 $c->write( $data )
2428
2429 Writes $data to the output stream. When using this method directly, you
2430 will need to manually set the C<Content-Length> header to the length of
2431 your output data, if known.
2432
2433 =cut
2434
2435 sub write {
2436     my $c = shift;
2437
2438     # Finalize headers if someone manually writes output
2439     $c->finalize_headers;
2440
2441     return $c->engine->write( $c, @_ );
2442 }
2443
2444 =head2 version
2445
2446 Returns the Catalyst version number. Mostly useful for "powered by"
2447 messages in template systems.
2448
2449 =cut
2450
2451 sub version { return $Catalyst::VERSION }
2452
2453 =head1 INTERNAL ACTIONS
2454
2455 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
2456 C<_ACTION>, and C<_END>. These are by default not shown in the private
2457 action table, but you can make them visible with a config parameter.
2458
2459     MyApp->config->{show_internal_actions} = 1;
2460
2461 =head1 CASE SENSITIVITY
2462
2463 By default Catalyst is not case sensitive, so C<MyApp::C::FOO::Bar> is
2464 mapped to C</foo/bar>. You can activate case sensitivity with a config
2465 parameter.
2466
2467     MyApp->config->{case_sensitive} = 1;
2468
2469 This causes C<MyApp::C::Foo::Bar> to map to C</Foo/Bar>.
2470
2471 =head1 ON-DEMAND PARSER
2472
2473 The request body is usually parsed at the beginning of a request,
2474 but if you want to handle input yourself, you can enable on-demand
2475 parsing with a config parameter.
2476
2477     MyApp->config->{parse_on_demand} = 1;
2478     
2479 =head1 PROXY SUPPORT
2480
2481 Many production servers operate using the common double-server approach,
2482 with a lightweight frontend web server passing requests to a larger
2483 backend server. An application running on the backend server must deal
2484 with two problems: the remote user always appears to be C<127.0.0.1> and
2485 the server's hostname will appear to be C<localhost> regardless of the
2486 virtual host that the user connected through.
2487
2488 Catalyst will automatically detect this situation when you are running
2489 the frontend and backend servers on the same machine. The following
2490 changes are made to the request.
2491
2492     $c->req->address is set to the user's real IP address, as read from 
2493     the HTTP X-Forwarded-For header.
2494     
2495     The host value for $c->req->base and $c->req->uri is set to the real
2496     host, as read from the HTTP X-Forwarded-Host header.
2497
2498 Obviously, your web server must support these headers for this to work.
2499
2500 In a more complex server farm environment where you may have your
2501 frontend proxy server(s) on different machines, you will need to set a
2502 configuration option to tell Catalyst to read the proxied data from the
2503 headers.
2504
2505     MyApp->config->{using_frontend_proxy} = 1;
2506     
2507 If you do not wish to use the proxy support at all, you may set:
2508
2509     MyApp->config->{ignore_frontend_proxy} = 1;
2510
2511 =head1 THREAD SAFETY
2512
2513 Catalyst has been tested under Apache 2's threading C<mpm_worker>,
2514 C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
2515 believe the Catalyst core to be thread-safe.
2516
2517 If you plan to operate in a threaded environment, remember that all other
2518 modules you are using must also be thread-safe. Some modules, most notably
2519 L<DBD::SQLite>, are not thread-safe.
2520
2521 =head1 SUPPORT
2522
2523 IRC:
2524
2525     Join #catalyst on irc.perl.org.
2526
2527 Mailing Lists:
2528
2529     http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
2530     http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
2531
2532 Web:
2533
2534     http://catalyst.perl.org
2535
2536 Wiki:
2537
2538     http://dev.catalyst.perl.org
2539
2540 =head1 SEE ALSO
2541
2542 =head2 L<Task::Catalyst> - All you need to start with Catalyst
2543
2544 =head2 L<Catalyst::Manual> - The Catalyst Manual
2545
2546 =head2 L<Catalyst::Component>, L<Catalyst::Base> - Base classes for components
2547
2548 =head2 L<Catalyst::Engine> - Core engine
2549
2550 =head2 L<Catalyst::Log> - Log class.
2551
2552 =head2 L<Catalyst::Request> - Request object
2553
2554 =head2 L<Catalyst::Response> - Response object
2555
2556 =head2 L<Catalyst::Test> - The test suite.
2557
2558 =head1 PROJECT FOUNDER
2559
2560 sri: Sebastian Riedel <sri@cpan.org>
2561
2562 =head1 CONTRIBUTORS
2563
2564 abw: Andy Wardley
2565
2566 acme: Leon Brocard <leon@astray.com>
2567
2568 Andrew Bramble
2569
2570 Andrew Ford
2571
2572 Andrew Ruthven
2573
2574 andyg: Andy Grundman <andy@hybridized.org>
2575
2576 audreyt: Audrey Tang
2577
2578 bricas: Brian Cassidy <bricas@cpan.org>
2579
2580 Caelum: Rafael Kitover <rkitover@io.com>
2581
2582 chansen: Christian Hansen
2583
2584 chicks: Christopher Hicks
2585
2586 David E. Wheeler
2587
2588 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
2589
2590 Drew Taylor
2591
2592 esskar: Sascha Kiefer
2593
2594 fireartist: Carl Franks <cfranks@cpan.org>
2595
2596 gabb: Danijel Milicevic
2597
2598 Gary Ashton Jones
2599
2600 Geoff Richards
2601
2602 ilmari: Dagfinn Ilmari MannsÃ¥ker <ilmari@ilmari.org>
2603
2604 jcamacho: Juan Camacho
2605
2606 jhannah: Jay Hannah <jay@jays.net>
2607
2608 Jody Belka
2609
2610 Johan Lindstrom
2611
2612 jon: Jon Schutz <jjschutz@cpan.org>
2613
2614 marcus: Marcus Ramberg <mramberg@cpan.org>
2615
2616 miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
2617
2618 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
2619
2620 mugwump: Sam Vilain
2621
2622 naughton: David Naughton
2623
2624 ningu: David Kamholz <dkamholz@cpan.org>
2625
2626 nothingmuch: Yuval Kogman <nothingmuch@woobling.org>
2627
2628 numa: Dan Sully <daniel@cpan.org>
2629
2630 obra: Jesse Vincent
2631
2632 omega: Andreas Marienborg
2633
2634 Oleg Kostyuk <cub.uanic@gmail.com>
2635
2636 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
2637
2638 rafl: Florian Ragwitz <rafl@debian.org>
2639
2640 sky: Arthur Bergman
2641
2642 the_jester: Jesse Sheidlower
2643
2644 t0m: Tomas Doran <bobtfish@bobtfish.net>
2645
2646 Ulf Edvinsson
2647
2648 willert: Sebastian Willert <willert@cpan.org>
2649
2650 =head1 LICENSE
2651
2652 This library is free software, you can redistribute it and/or modify it under
2653 the same terms as Perl itself.
2654
2655 =cut
2656
2657 no Moose;
2658
2659 __PACKAGE__->meta->make_immutable;
2660
2661 1;