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