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