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