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