Catalyst::View::Mason fixed
[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 Scope::Upper ();
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, this is stupid and evil.
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     Scope::Upper::reap(sub {
1028         my $meta = $class->Moose::Object::meta();
1029         $meta->make_immutable unless $meta->is_immutable;
1030     }, 1);
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     return if $c->request->_has_body;
1751
1752     # Initialize on-demand data
1753     $c->engine->prepare_body( $c, @_ );
1754     $c->prepare_parameters;
1755     $c->prepare_uploads;
1756
1757     if ( $c->debug && keys %{ $c->req->body_parameters } ) {
1758         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1759         for my $key ( sort keys %{ $c->req->body_parameters } ) {
1760             my $param = $c->req->body_parameters->{$key};
1761             my $value = defined($param) ? $param : '';
1762             $t->row( $key,
1763                 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1764         }
1765         $c->log->debug( "Body Parameters are:\n" . $t->draw );
1766     }
1767 }
1768
1769 =head2 $c->prepare_body_chunk( $chunk )
1770
1771 Prepares a chunk of data before sending it to L<HTTP::Body>.
1772
1773 See L<Catalyst::Engine>.
1774
1775 =cut
1776
1777 sub prepare_body_chunk {
1778     my $c = shift;
1779     $c->engine->prepare_body_chunk( $c, @_ );
1780 }
1781
1782 =head2 $c->prepare_body_parameters
1783
1784 Prepares body parameters.
1785
1786 =cut
1787
1788 sub prepare_body_parameters {
1789     my $c = shift;
1790     $c->engine->prepare_body_parameters( $c, @_ );
1791 }
1792
1793 =head2 $c->prepare_connection
1794
1795 Prepares connection.
1796
1797 =cut
1798
1799 sub prepare_connection {
1800     my $c = shift;
1801     $c->engine->prepare_connection( $c, @_ );
1802 }
1803
1804 =head2 $c->prepare_cookies
1805
1806 Prepares cookies.
1807
1808 =cut
1809
1810 sub prepare_cookies { my $c = shift; $c->engine->prepare_cookies( $c, @_ ) }
1811
1812 =head2 $c->prepare_headers
1813
1814 Prepares headers.
1815
1816 =cut
1817
1818 sub prepare_headers { my $c = shift; $c->engine->prepare_headers( $c, @_ ) }
1819
1820 =head2 $c->prepare_parameters
1821
1822 Prepares parameters.
1823
1824 =cut
1825
1826 sub prepare_parameters {
1827     my $c = shift;
1828     $c->prepare_body_parameters;
1829     $c->engine->prepare_parameters( $c, @_ );
1830 }
1831
1832 =head2 $c->prepare_path
1833
1834 Prepares path and base.
1835
1836 =cut
1837
1838 sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) }
1839
1840 =head2 $c->prepare_query_parameters
1841
1842 Prepares query parameters.
1843
1844 =cut
1845
1846 sub prepare_query_parameters {
1847     my $c = shift;
1848
1849     $c->engine->prepare_query_parameters( $c, @_ );
1850
1851     if ( $c->debug && keys %{ $c->request->query_parameters } ) {
1852         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1853         for my $key ( sort keys %{ $c->req->query_parameters } ) {
1854             my $param = $c->req->query_parameters->{$key};
1855             my $value = defined($param) ? $param : '';
1856             $t->row( $key,
1857                 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1858         }
1859         $c->log->debug( "Query Parameters are:\n" . $t->draw );
1860     }
1861 }
1862
1863 =head2 $c->prepare_read
1864
1865 Prepares the input for reading.
1866
1867 =cut
1868
1869 sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
1870
1871 =head2 $c->prepare_request
1872
1873 Prepares the engine request.
1874
1875 =cut
1876
1877 sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
1878
1879 =head2 $c->prepare_uploads
1880
1881 Prepares uploads.
1882
1883 =cut
1884
1885 sub prepare_uploads {
1886     my $c = shift;
1887
1888     $c->engine->prepare_uploads( $c, @_ );
1889
1890     if ( $c->debug && keys %{ $c->request->uploads } ) {
1891         my $t = Text::SimpleTable->new(
1892             [ 12, 'Parameter' ],
1893             [ 26, 'Filename' ],
1894             [ 18, 'Type' ],
1895             [ 9,  'Size' ]
1896         );
1897         for my $key ( sort keys %{ $c->request->uploads } ) {
1898             my $upload = $c->request->uploads->{$key};
1899             for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
1900                 $t->row( $key, $u->filename, $u->type, $u->size );
1901             }
1902         }
1903         $c->log->debug( "File Uploads are:\n" . $t->draw );
1904     }
1905 }
1906
1907 =head2 $c->prepare_write
1908
1909 Prepares the output for writing.
1910
1911 =cut
1912
1913 sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
1914
1915 =head2 $c->request_class
1916
1917 Returns or sets the request class.
1918
1919 =head2 $c->response_class
1920
1921 Returns or sets the response class.
1922
1923 =head2 $c->read( [$maxlength] )
1924
1925 Reads a chunk of data from the request body. This method is designed to
1926 be used in a while loop, reading C<$maxlength> bytes on every call.
1927 C<$maxlength> defaults to the size of the request if not specified.
1928
1929 You have to set C<< MyApp->config->{parse_on_demand} >> to use this
1930 directly.
1931
1932 Warning: If you use read(), Catalyst will not process the body,
1933 so you will not be able to access POST parameters or file uploads via
1934 $c->request.  You must handle all body parsing yourself.
1935
1936 =cut
1937
1938 sub read { my $c = shift; return $c->engine->read( $c, @_ ) }
1939
1940 =head2 $c->run
1941
1942 Starts the engine.
1943
1944 =cut
1945
1946 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
1947
1948 =head2 $c->set_action( $action, $code, $namespace, $attrs )
1949
1950 Sets an action in a given namespace.
1951
1952 =cut
1953
1954 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
1955
1956 =head2 $c->setup_actions($component)
1957
1958 Sets up actions for a component.
1959
1960 =cut
1961
1962 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
1963
1964 =head2 $c->setup_components
1965
1966 Sets up components. Specify a C<setup_components> config option to pass
1967 additional options directly to L<Module::Pluggable>. To add additional
1968 search paths, specify a key named C<search_extra> as an array
1969 reference. Items in the array beginning with C<::> will have the
1970 application class name prepended to them.
1971
1972 All components found will also have any 
1973 L<Devel::InnerPackage|inner packages> loaded and set up as components.
1974 Note, that modules which are B<not> an I<inner package> of the main
1975 file namespace loaded will not be instantiated as components.
1976
1977 =cut
1978
1979 sub setup_components {
1980     my $class = shift;
1981
1982     my @paths   = qw( ::Controller ::C ::Model ::M ::View ::V );
1983     my $config  = $class->config->{ setup_components };
1984     my $extra   = delete $config->{ search_extra } || [];
1985     
1986     push @paths, @$extra;
1987         
1988     my $locator = Module::Pluggable::Object->new(
1989         search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
1990         %$config
1991     );
1992
1993     my @comps = sort { length $a <=> length $b } $locator->plugins;
1994     my %comps = map { $_ => 1 } @comps;
1995     
1996     for my $component ( @comps ) {
1997
1998         # We pass ignore_loaded here so that overlay files for (e.g.)
1999         # Model::DBI::Schema sub-classes are loaded - if it's in @comps
2000         # we know M::P::O found a file on disk so this is safe
2001
2002         Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
2003         #Class::MOP::load_class($component);
2004
2005         my $module  = $class->setup_component( $component );
2006         my %modules = (
2007             $component => $module,
2008             map {
2009                 $_ => $class->setup_component( $_ )
2010             } grep { 
2011               not exists $comps{$_}
2012             } Devel::InnerPackage::list_packages( $component )
2013         );
2014         
2015         for my $key ( keys %modules ) {
2016             $class->components->{ $key } = $modules{ $key };
2017         }
2018     }
2019 }
2020
2021 =head2 $c->setup_component
2022
2023 =cut
2024
2025 sub setup_component {
2026     my( $class, $component ) = @_;
2027
2028     unless ( $component->can( 'COMPONENT' ) ) {
2029         return $component;
2030     }
2031
2032     my $suffix = Catalyst::Utils::class2classsuffix( $component );
2033     my $config = $class->config->{ $suffix } || {};
2034
2035     my $instance = eval { $component->COMPONENT( $class, $config ); };
2036
2037     if ( my $error = $@ ) {
2038         chomp $error;
2039         Catalyst::Exception->throw(
2040             message => qq/Couldn't instantiate component "$component", "$error"/
2041         );
2042     }
2043
2044     Catalyst::Exception->throw(
2045         message =>
2046         qq/Couldn't instantiate component "$component", "COMPONENT() didn't return an object-like value"/
2047     ) unless blessed($instance);
2048
2049     return $instance;
2050 }
2051
2052 =head2 $c->setup_dispatcher
2053
2054 Sets up dispatcher.
2055
2056 =cut
2057
2058 sub setup_dispatcher {
2059     my ( $class, $dispatcher ) = @_;
2060
2061     if ($dispatcher) {
2062         $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
2063     }
2064
2065     if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
2066         $dispatcher = 'Catalyst::Dispatcher::' . $env;
2067     }
2068
2069     unless ($dispatcher) {
2070         $dispatcher = $class->dispatcher_class;
2071     }
2072
2073     Class::MOP::load_class($dispatcher);
2074
2075     # dispatcher instance
2076     $class->dispatcher( $dispatcher->new );
2077 }
2078
2079 =head2 $c->setup_engine
2080
2081 Sets up engine.
2082
2083 =cut
2084
2085 sub setup_engine {
2086     my ( $class, $engine ) = @_;
2087
2088     if ($engine) {
2089         $engine = 'Catalyst::Engine::' . $engine;
2090     }
2091
2092     if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
2093         $engine = 'Catalyst::Engine::' . $env;
2094     }
2095
2096     if ( $ENV{MOD_PERL} ) {
2097         my $meta = $class->Class::MOP::Object::meta();
2098         
2099         # create the apache method
2100         $meta->add_method('apache' => sub { shift->engine->apache });
2101
2102         my ( $software, $version ) =
2103           $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
2104
2105         $version =~ s/_//g;
2106         $version =~ s/(\.[^.]+)\./$1/g;
2107
2108         if ( $software eq 'mod_perl' ) {
2109
2110             if ( !$engine ) {
2111
2112                 if ( $version >= 1.99922 ) {
2113                     $engine = 'Catalyst::Engine::Apache2::MP20';
2114                 }
2115
2116                 elsif ( $version >= 1.9901 ) {
2117                     $engine = 'Catalyst::Engine::Apache2::MP19';
2118                 }
2119
2120                 elsif ( $version >= 1.24 ) {
2121                     $engine = 'Catalyst::Engine::Apache::MP13';
2122                 }
2123
2124                 else {
2125                     Catalyst::Exception->throw( message =>
2126                           qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
2127                 }
2128
2129             }
2130
2131             # install the correct mod_perl handler
2132             if ( $version >= 1.9901 ) {
2133                 *handler = sub  : method {
2134                     shift->handle_request(@_);
2135                 };
2136             }
2137             else {
2138                 *handler = sub ($$) { shift->handle_request(@_) };
2139             }
2140
2141         }
2142
2143         elsif ( $software eq 'Zeus-Perl' ) {
2144             $engine = 'Catalyst::Engine::Zeus';
2145         }
2146
2147         else {
2148             Catalyst::Exception->throw(
2149                 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
2150         }
2151     }
2152
2153     unless ($engine) {
2154         $engine = $class->engine_class;
2155     }
2156
2157     Class::MOP::load_class($engine);
2158
2159     # check for old engines that are no longer compatible
2160     my $old_engine;
2161     if ( $engine->isa('Catalyst::Engine::Apache')
2162         && !Catalyst::Engine::Apache->VERSION )
2163     {
2164         $old_engine = 1;
2165     }
2166
2167     elsif ( $engine->isa('Catalyst::Engine::Server::Base')
2168         && Catalyst::Engine::Server->VERSION le '0.02' )
2169     {
2170         $old_engine = 1;
2171     }
2172
2173     elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
2174         && $engine->VERSION eq '0.01' )
2175     {
2176         $old_engine = 1;
2177     }
2178
2179     elsif ($engine->isa('Catalyst::Engine::Zeus')
2180         && $engine->VERSION eq '0.01' )
2181     {
2182         $old_engine = 1;
2183     }
2184
2185     if ($old_engine) {
2186         Catalyst::Exception->throw( message =>
2187               qq/Engine "$engine" is not supported by this version of Catalyst/
2188         );
2189     }
2190
2191     # engine instance
2192     $class->engine( $engine->new );
2193 }
2194
2195 =head2 $c->setup_home
2196
2197 Sets up the home directory.
2198
2199 =cut
2200
2201 sub setup_home {
2202     my ( $class, $home ) = @_;
2203
2204     if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
2205         $home = $env;
2206     }
2207
2208     $home ||= Catalyst::Utils::home($class);
2209
2210     if ($home) {
2211         #I remember recently being scolded for assigning config values like this
2212         $class->config->{home} ||= $home;
2213         $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
2214     }
2215 }
2216
2217 =head2 $c->setup_log
2218
2219 Sets up log by instantiating a L<Catalyst::Log|Catalyst::Log> object and
2220 passing it to C<log()>. Pass in a comma-delimited list of levels to set the
2221 log to.
2222  
2223 This method also installs a C<debug> method that returns a true value into the
2224 catalyst subclass if the "debug" level is passed in the comma-delimited list,
2225 or if the C<$CATALYST_DEBUG> environment variable is set to a true value.
2226
2227 Note that if the log has already been setup, by either a previous call to
2228 C<setup_log> or by a call such as C<< __PACKAGE__->log( MyLogger->new ) >>,
2229 that this method won't actually set up the log.
2230
2231 =cut
2232
2233 sub setup_log {
2234     my ( $class, $levels ) = @_;
2235
2236     my %levels;
2237     unless ( $class->log ) {
2238         $levels ||= '';
2239         $levels =~ s/^\s+//;
2240         $levels =~ s/\s+$//;
2241         %levels = map { $_ => 1 } split /\s*,\s*/, $levels || '';
2242         $class->log( Catalyst::Log->new(keys %levels) );
2243     }
2244
2245     my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
2246     if ( defined($env_debug) or $levels{debug} ) {
2247         $class->Class::MOP::Object::meta()->add_method('debug' => sub { 1 });
2248         $class->log->debug('Debug messages enabled');
2249     }
2250 }
2251
2252 =head2 $c->setup_plugins
2253
2254 Sets up plugins.
2255
2256 =cut
2257
2258 =head2 $c->setup_stats
2259
2260 Sets up timing statistics class.
2261
2262 =cut
2263
2264 sub setup_stats {
2265     my ( $class, $stats ) = @_;
2266
2267     Catalyst::Utils::ensure_class_loaded($class->stats_class);
2268
2269     my $env = Catalyst::Utils::env_value( $class, 'STATS' );
2270     if ( defined($env) ? $env : ($stats || $class->debug ) ) {
2271         $class->Class::MOP::Object::meta()->add_method('use_stats' => sub { 1 });
2272         $class->log->debug('Statistics enabled');
2273     }
2274 }
2275
2276
2277 =head2 $c->registered_plugins 
2278
2279 Returns a sorted list of the plugins which have either been stated in the
2280 import list or which have been added via C<< MyApp->plugin(@args); >>.
2281
2282 If passed a given plugin name, it will report a boolean value indicating
2283 whether or not that plugin is loaded.  A fully qualified name is required if
2284 the plugin name does not begin with C<Catalyst::Plugin::>.
2285
2286  if ($c->registered_plugins('Some::Plugin')) {
2287      ...
2288  }
2289
2290 =cut
2291
2292 {
2293
2294     sub registered_plugins {
2295         my $proto = shift;
2296         return sort keys %{ $proto->_plugins } unless @_;
2297         my $plugin = shift;
2298         return 1 if exists $proto->_plugins->{$plugin};
2299         return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
2300     }
2301
2302     sub _register_plugin {
2303         my ( $proto, $plugin, $instant ) = @_;
2304         my $class = ref $proto || $proto;
2305
2306         # no ignore_loaded here, the plugin may already have been
2307         # defined in memory and we don't want to error on "no file" if so
2308
2309         Class::MOP::load_class( $plugin );
2310
2311         $proto->_plugins->{$plugin} = 1;
2312         unless ($instant) {
2313             no strict 'refs';
2314             if ( my $meta = $class->Class::MOP::Object::meta() ) {
2315               my @superclasses = ($plugin, $meta->superclasses );
2316               $meta->superclasses(@superclasses);
2317             } else {
2318               unshift @{"$class\::ISA"}, $plugin;
2319             }
2320         }
2321         return $class;
2322     }
2323
2324     sub setup_plugins {
2325         my ( $class, $plugins ) = @_;
2326
2327         $class->_plugins( {} ) unless $class->_plugins;
2328         $plugins ||= [];
2329         for my $plugin ( reverse @$plugins ) {
2330
2331             unless ( $plugin =~ s/\A\+// ) {
2332                 $plugin = "Catalyst::Plugin::$plugin";
2333             }
2334
2335             $class->_register_plugin($plugin);
2336         }
2337     }
2338 }
2339
2340 =head2 $c->stack
2341
2342 Returns an arrayref of the internal execution stack (actions that are
2343 currently executing).
2344
2345 =head2 $c->stats_class
2346
2347 Returns or sets the stats (timing statistics) class.
2348
2349 =head2 $c->use_stats
2350
2351 Returns 1 when stats collection is enabled.  Stats collection is enabled
2352 when the -Stats options is set, debug is on or when the <MYAPP>_STATS
2353 environment variable is set.
2354
2355 Note that this is a static method, not an accessor and should be overloaded
2356 by declaring "sub use_stats { 1 }" in your MyApp.pm, not by calling $c->use_stats(1).
2357
2358 =cut
2359
2360 sub use_stats { 0 }
2361
2362
2363 =head2 $c->write( $data )
2364
2365 Writes $data to the output stream. When using this method directly, you
2366 will need to manually set the C<Content-Length> header to the length of
2367 your output data, if known.
2368
2369 =cut
2370
2371 sub write {
2372     my $c = shift;
2373
2374     # Finalize headers if someone manually writes output
2375     $c->finalize_headers;
2376
2377     return $c->engine->write( $c, @_ );
2378 }
2379
2380 =head2 version
2381
2382 Returns the Catalyst version number. Mostly useful for "powered by"
2383 messages in template systems.
2384
2385 =cut
2386
2387 sub version { return $Catalyst::VERSION }
2388
2389 =head1 INTERNAL ACTIONS
2390
2391 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
2392 C<_ACTION>, and C<_END>. These are by default not shown in the private
2393 action table, but you can make them visible with a config parameter.
2394
2395     MyApp->config->{show_internal_actions} = 1;
2396
2397 =head1 CASE SENSITIVITY
2398
2399 By default Catalyst is not case sensitive, so C<MyApp::C::FOO::Bar> is
2400 mapped to C</foo/bar>. You can activate case sensitivity with a config
2401 parameter.
2402
2403     MyApp->config->{case_sensitive} = 1;
2404
2405 This causes C<MyApp::C::Foo::Bar> to map to C</Foo/Bar>.
2406
2407 =head1 ON-DEMAND PARSER
2408
2409 The request body is usually parsed at the beginning of a request,
2410 but if you want to handle input yourself, you can enable on-demand
2411 parsing with a config parameter.
2412
2413     MyApp->config->{parse_on_demand} = 1;
2414     
2415 =head1 PROXY SUPPORT
2416
2417 Many production servers operate using the common double-server approach,
2418 with a lightweight frontend web server passing requests to a larger
2419 backend server. An application running on the backend server must deal
2420 with two problems: the remote user always appears to be C<127.0.0.1> and
2421 the server's hostname will appear to be C<localhost> regardless of the
2422 virtual host that the user connected through.
2423
2424 Catalyst will automatically detect this situation when you are running
2425 the frontend and backend servers on the same machine. The following
2426 changes are made to the request.
2427
2428     $c->req->address is set to the user's real IP address, as read from 
2429     the HTTP X-Forwarded-For header.
2430     
2431     The host value for $c->req->base and $c->req->uri is set to the real
2432     host, as read from the HTTP X-Forwarded-Host header.
2433
2434 Obviously, your web server must support these headers for this to work.
2435
2436 In a more complex server farm environment where you may have your
2437 frontend proxy server(s) on different machines, you will need to set a
2438 configuration option to tell Catalyst to read the proxied data from the
2439 headers.
2440
2441     MyApp->config->{using_frontend_proxy} = 1;
2442     
2443 If you do not wish to use the proxy support at all, you may set:
2444
2445     MyApp->config->{ignore_frontend_proxy} = 1;
2446
2447 =head1 THREAD SAFETY
2448
2449 Catalyst has been tested under Apache 2's threading C<mpm_worker>,
2450 C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
2451 believe the Catalyst core to be thread-safe.
2452
2453 If you plan to operate in a threaded environment, remember that all other
2454 modules you are using must also be thread-safe. Some modules, most notably
2455 L<DBD::SQLite>, are not thread-safe.
2456
2457 =head1 SUPPORT
2458
2459 IRC:
2460
2461     Join #catalyst on irc.perl.org.
2462
2463 Mailing Lists:
2464
2465     http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
2466     http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
2467
2468 Web:
2469
2470     http://catalyst.perl.org
2471
2472 Wiki:
2473
2474     http://dev.catalyst.perl.org
2475
2476 =head1 SEE ALSO
2477
2478 =head2 L<Task::Catalyst> - All you need to start with Catalyst
2479
2480 =head2 L<Catalyst::Manual> - The Catalyst Manual
2481
2482 =head2 L<Catalyst::Component>, L<Catalyst::Base> - Base classes for components
2483
2484 =head2 L<Catalyst::Engine> - Core engine
2485
2486 =head2 L<Catalyst::Log> - Log class.
2487
2488 =head2 L<Catalyst::Request> - Request object
2489
2490 =head2 L<Catalyst::Response> - Response object
2491
2492 =head2 L<Catalyst::Test> - The test suite.
2493
2494 =head1 PROJECT FOUNDER
2495
2496 sri: Sebastian Riedel <sri@cpan.org>
2497
2498 =head1 CONTRIBUTORS
2499
2500 abw: Andy Wardley
2501
2502 acme: Leon Brocard <leon@astray.com>
2503
2504 Andrew Bramble
2505
2506 Andrew Ford
2507
2508 Andrew Ruthven
2509
2510 andyg: Andy Grundman <andy@hybridized.org>
2511
2512 audreyt: Audrey Tang
2513
2514 bricas: Brian Cassidy <bricas@cpan.org>
2515
2516 Caelum: Rafael Kitover <rkitover@io.com>
2517
2518 chansen: Christian Hansen
2519
2520 chicks: Christopher Hicks
2521
2522 David E. Wheeler
2523
2524 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
2525
2526 Drew Taylor
2527
2528 esskar: Sascha Kiefer
2529
2530 fireartist: Carl Franks <cfranks@cpan.org>
2531
2532 gabb: Danijel Milicevic
2533
2534 Gary Ashton Jones
2535
2536 Geoff Richards
2537
2538 ilmari: Dagfinn Ilmari MannsÃ¥ker <ilmari@ilmari.org>
2539
2540 jcamacho: Juan Camacho
2541
2542 Jody Belka
2543
2544 Johan Lindstrom
2545
2546 jon: Jon Schutz <jjschutz@cpan.org>
2547
2548 marcus: Marcus Ramberg <mramberg@cpan.org>
2549
2550 miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
2551
2552 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
2553
2554 mugwump: Sam Vilain
2555
2556 naughton: David Naughton
2557
2558 ningu: David Kamholz <dkamholz@cpan.org>
2559
2560 nothingmuch: Yuval Kogman <nothingmuch@woobling.org>
2561
2562 numa: Dan Sully <daniel@cpan.org>
2563
2564 obra: Jesse Vincent
2565
2566 omega: Andreas Marienborg
2567
2568 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
2569
2570 rafl: Florian Ragwitz <rafl@debian.org>
2571
2572 sky: Arthur Bergman
2573
2574 the_jester: Jesse Sheidlower
2575
2576 Ulf Edvinsson
2577
2578 willert: Sebastian Willert <willert@cpan.org>
2579
2580 =head1 LICENSE
2581
2582 This library is free software, you can redistribute it and/or modify it under
2583 the same terms as Perl itself.
2584
2585 =cut
2586
2587 no Moose;
2588
2589 __PACKAGE__->meta->make_immutable;
2590
2591 1;