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