Doc changes for passing CaptureArgs
[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         $path = $c->dispatcher->uri_for_action($path, $captures);
1146         return undef unless defined($path);
1147         $path = '/' if $path eq '';
1148     }
1149
1150     undef($path) if (defined $path && $path eq '');
1151
1152     my $params =
1153       ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
1154
1155     carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
1156     s/([^$URI::uric])/$URI::Escape::escapes{$1}/go for @args;
1157
1158     unshift(@args, $path);
1159
1160     unless (defined $path && $path =~ s!^/!!) { # in-place strip
1161         my $namespace = $c->namespace;
1162         if (defined $path) { # cheesy hack to handle path '../foo'
1163            $namespace =~ s{(?:^|/)[^/]+$}{} while $args[0] =~ s{^\.\./}{};
1164         }
1165         unshift(@args, $namespace || '');
1166     }
1167     
1168     # join args with '/', or a blank string
1169     my $args = join('/', grep { defined($_) } @args);
1170     $args =~ s/\?/%3F/g; # STUPID STUPID SPECIAL CASE
1171     $args =~ s!^/+!!;
1172     my $base = $c->req->base;
1173     my $class = ref($base);
1174     $base =~ s{(?<!/)$}{/};
1175
1176     my $query = '';
1177
1178     if (my @keys = keys %$params) {
1179       # somewhat lifted from URI::_query's query_form
1180       $query = '?'.join('&', map {
1181           my $val = $params->{$_};
1182           s/([;\/?:@&=+,\$\[\]%])/$URI::Escape::escapes{$1}/go;
1183           s/ /+/g;
1184           my $key = $_;
1185           $val = '' unless defined $val;
1186           (map {
1187               $_ = "$_";
1188               utf8::encode( $_ ) if utf8::is_utf8($_);
1189               # using the URI::Escape pattern here so utf8 chars survive
1190               s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
1191               s/ /+/g;
1192               "${key}=$_"; } ( ref $val eq 'ARRAY' ? @$val : $val ));
1193       } @keys);
1194     }
1195
1196     my $res = bless(\"${base}${args}${query}", $class);
1197     $res;
1198 }
1199
1200 =head2 $c->welcome_message
1201
1202 Returns the Catalyst welcome HTML page.
1203
1204 =cut
1205
1206 sub welcome_message {
1207     my $c      = shift;
1208     my $name   = $c->config->{name};
1209     my $logo   = $c->uri_for('/static/images/catalyst_logo.png');
1210     my $prefix = Catalyst::Utils::appprefix( ref $c );
1211     $c->response->content_type('text/html; charset=utf-8');
1212     return <<"EOF";
1213 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1214     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1215 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
1216     <head>
1217     <meta http-equiv="Content-Language" content="en" />
1218     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1219         <title>$name on Catalyst $VERSION</title>
1220         <style type="text/css">
1221             body {
1222                 color: #000;
1223                 background-color: #eee;
1224             }
1225             div#content {
1226                 width: 640px;
1227                 margin-left: auto;
1228                 margin-right: auto;
1229                 margin-top: 10px;
1230                 margin-bottom: 10px;
1231                 text-align: left;
1232                 background-color: #ccc;
1233                 border: 1px solid #aaa;
1234             }
1235             p, h1, h2 {
1236                 margin-left: 20px;
1237                 margin-right: 20px;
1238                 font-family: verdana, tahoma, sans-serif;
1239             }
1240             a {
1241                 font-family: verdana, tahoma, sans-serif;
1242             }
1243             :link, :visited {
1244                     text-decoration: none;
1245                     color: #b00;
1246                     border-bottom: 1px dotted #bbb;
1247             }
1248             :link:hover, :visited:hover {
1249                     color: #555;
1250             }
1251             div#topbar {
1252                 margin: 0px;
1253             }
1254             pre {
1255                 margin: 10px;
1256                 padding: 8px;
1257             }
1258             div#answers {
1259                 padding: 8px;
1260                 margin: 10px;
1261                 background-color: #fff;
1262                 border: 1px solid #aaa;
1263             }
1264             h1 {
1265                 font-size: 0.9em;
1266                 font-weight: normal;
1267                 text-align: center;
1268             }
1269             h2 {
1270                 font-size: 1.0em;
1271             }
1272             p {
1273                 font-size: 0.9em;
1274             }
1275             p img {
1276                 float: right;
1277                 margin-left: 10px;
1278             }
1279             span#appname {
1280                 font-weight: bold;
1281                 font-size: 1.6em;
1282             }
1283         </style>
1284     </head>
1285     <body>
1286         <div id="content">
1287             <div id="topbar">
1288                 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
1289                     $VERSION</h1>
1290              </div>
1291              <div id="answers">
1292                  <p>
1293                  <img src="$logo" alt="Catalyst Logo" />
1294                  </p>
1295                  <p>Welcome to the  world of Catalyst.
1296                     This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
1297                     framework will make web development something you had
1298                     never expected it to be: Fun, rewarding, and quick.</p>
1299                  <h2>What to do now?</h2>
1300                  <p>That really depends  on what <b>you</b> want to do.
1301                     We do, however, provide you with a few starting points.</p>
1302                  <p>If you want to jump right into web development with Catalyst
1303                     you might want to start with a tutorial.</p>
1304 <pre>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
1305 </pre>
1306 <p>Afterwards you can go on to check out a more complete look at our features.</p>
1307 <pre>
1308 <code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
1309 <!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
1310 </code></pre>
1311                  <h2>What to do next?</h2>
1312                  <p>Next it's time to write an actual application. Use the
1313                     helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&amp;mode=all">controllers</a>,
1314                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&amp;mode=all">models</a>, and
1315                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&amp;mode=all">views</a>;
1316                     they can save you a lot of work.</p>
1317                     <pre><code>script/${prefix}_create.pl -help</code></pre>
1318                     <p>Also, be sure to check out the vast and growing
1319                     collection of <a href="http://search.cpan.org/search?query=Catalyst">plugins for Catalyst on CPAN</a>;
1320                     you are likely to find what you need there.
1321                     </p>
1322
1323                  <h2>Need help?</h2>
1324                  <p>Catalyst has a very active community. Here are the main places to
1325                     get in touch with us.</p>
1326                  <ul>
1327                      <li>
1328                          <a href="http://dev.catalyst.perl.org">Wiki</a>
1329                      </li>
1330                      <li>
1331                          <a href="http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst">Mailing-List</a>
1332                      </li>
1333                      <li>
1334                          <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
1335                      </li>
1336                  </ul>
1337                  <h2>In conclusion</h2>
1338                  <p>The Catalyst team hopes you will enjoy using Catalyst as much 
1339                     as we enjoyed making it. Please contact us if you have ideas
1340                     for improvement or other feedback.</p>
1341              </div>
1342          </div>
1343     </body>
1344 </html>
1345 EOF
1346 }
1347
1348 =head1 INTERNAL METHODS
1349
1350 These methods are not meant to be used by end users.
1351
1352 =head2 $c->components
1353
1354 Returns a hash of components.
1355
1356 =head2 $c->context_class
1357
1358 Returns or sets the context class.
1359
1360 =head2 $c->counter
1361
1362 Returns a hashref containing coderefs and execution counts (needed for
1363 deep recursion detection).
1364
1365 =head2 $c->depth
1366
1367 Returns the number of actions on the current internal execution stack.
1368
1369 =head2 $c->dispatch
1370
1371 Dispatches a request to actions.
1372
1373 =cut
1374
1375 sub dispatch { my $c = shift; $c->dispatcher->dispatch( $c, @_ ) }
1376
1377 =head2 $c->dispatcher_class
1378
1379 Returns or sets the dispatcher class.
1380
1381 =head2 $c->dump_these
1382
1383 Returns a list of 2-element array references (name, structure) pairs
1384 that will be dumped on the error page in debug mode.
1385
1386 =cut
1387
1388 sub dump_these {
1389     my $c = shift;
1390     [ Request => $c->req ], 
1391     [ Response => $c->res ], 
1392     [ Stash => $c->stash ],
1393     [ Config => $c->config ];
1394 }
1395
1396 =head2 $c->engine_class
1397
1398 Returns or sets the engine class.
1399
1400 =head2 $c->execute( $class, $coderef )
1401
1402 Execute a coderef in given class and catch exceptions. Errors are available
1403 via $c->error.
1404
1405 =cut
1406
1407 sub execute {
1408     my ( $c, $class, $code ) = @_;
1409     $class = $c->component($class) || $class;
1410     $c->state(0);
1411
1412     if ( $c->depth >= $RECURSION ) {
1413         my $action = $code->reverse();
1414         $action = "/$action" unless $action =~ /->/;
1415         my $error = qq/Deep recursion detected calling "${action}"/;
1416         $c->log->error($error);
1417         $c->error($error);
1418         $c->state(0);
1419         return $c->state;
1420     }
1421
1422     my $stats_info = $c->_stats_start_execute( $code ) if $c->use_stats;
1423
1424     push( @{ $c->stack }, $code );
1425     
1426     eval { $c->state( $code->execute( $class, $c, @{ $c->req->args } ) || 0 ) };
1427
1428     $c->_stats_finish_execute( $stats_info ) if $c->use_stats and $stats_info;
1429     
1430     my $last = pop( @{ $c->stack } );
1431
1432     if ( my $error = $@ ) {
1433         if ( !ref($error) and $error eq $DETACH ) {
1434             die $DETACH if($c->depth > 1);
1435         }
1436         elsif ( !ref($error) and $error eq $GO ) {
1437             die $GO if($c->depth > 0);
1438         }
1439         else {
1440             unless ( ref $error ) {
1441                 no warnings 'uninitialized';
1442                 chomp $error;
1443                 my $class = $last->class;
1444                 my $name  = $last->name;
1445                 $error = qq/Caught exception in $class->$name "$error"/;
1446             }
1447             $c->error($error);
1448             $c->state(0);
1449         }
1450     }
1451     return $c->state;
1452 }
1453
1454 sub _stats_start_execute {
1455     my ( $c, $code ) = @_;
1456
1457     return if ( ( $code->name =~ /^_.*/ )
1458         && ( !$c->config->{show_internal_actions} ) );
1459
1460     my $action_name = $code->reverse();
1461     $c->counter->{$action_name}++;
1462
1463     my $action = $action_name;
1464     $action = "/$action" unless $action =~ /->/;
1465
1466     # determine if the call was the result of a forward
1467     # this is done by walking up the call stack and looking for a calling
1468     # sub of Catalyst::forward before the eval
1469     my $callsub = q{};
1470     for my $index ( 2 .. 11 ) {
1471         last
1472         if ( ( caller($index) )[0] eq 'Catalyst'
1473             && ( caller($index) )[3] eq '(eval)' );
1474
1475         if ( ( caller($index) )[3] =~ /forward$/ ) {
1476             $callsub = ( caller($index) )[3];
1477             $action  = "-> $action";
1478             last;
1479         }
1480     }
1481
1482     my $uid = $action_name . $c->counter->{$action_name};
1483
1484     # is this a root-level call or a forwarded call?
1485     if ( $callsub =~ /forward$/ ) {
1486
1487         # forward, locate the caller
1488         if ( my $parent = $c->stack->[-1] ) {
1489             $c->stats->profile(
1490                 begin  => $action, 
1491                 parent => "$parent" . $c->counter->{"$parent"},
1492                 uid    => $uid,
1493             );
1494         }
1495         else {
1496
1497             # forward with no caller may come from a plugin
1498             $c->stats->profile(
1499                 begin => $action,
1500                 uid   => $uid,
1501             );
1502         }
1503     }
1504     else {
1505         
1506         # root-level call
1507         $c->stats->profile(
1508             begin => $action,
1509             uid   => $uid,
1510         );
1511     }
1512     return $action;
1513
1514 }
1515
1516 sub _stats_finish_execute {
1517     my ( $c, $info ) = @_;
1518     $c->stats->profile( end => $info );
1519 }
1520
1521 =head2 $c->_localize_fields( sub { }, \%keys );
1522
1523 =cut
1524
1525 #Why does this exist? This is no longer safe and WILL NOT WORK.
1526 # it doesnt seem to be used anywhere. can we remove it?
1527 sub _localize_fields {
1528     my ( $c, $localized, $code ) = ( @_ );
1529
1530     my $request = delete $localized->{request} || {};
1531     my $response = delete $localized->{response} || {};
1532     
1533     local @{ $c }{ keys %$localized } = values %$localized;
1534     local @{ $c->request }{ keys %$request } = values %$request;
1535     local @{ $c->response }{ keys %$response } = values %$response;
1536
1537     $code->();
1538 }
1539
1540 =head2 $c->finalize
1541
1542 Finalizes the request.
1543
1544 =cut
1545
1546 sub finalize {
1547     my $c = shift;
1548
1549     for my $error ( @{ $c->error } ) {
1550         $c->log->error($error);
1551     }
1552
1553     # Allow engine to handle finalize flow (for POE)
1554     my $engine = $c->engine;
1555     if ( my $code = $engine->can('finalize') ) {
1556         $engine->$code($c);
1557     }
1558     else {
1559
1560         $c->finalize_uploads;
1561
1562         # Error
1563         if ( $#{ $c->error } >= 0 ) {
1564             $c->finalize_error;
1565         }
1566
1567         $c->finalize_headers;
1568
1569         # HEAD request
1570         if ( $c->request->method eq 'HEAD' ) {
1571             $c->response->body('');
1572         }
1573
1574         $c->finalize_body;
1575     }
1576     
1577     if ($c->use_stats) {        
1578         my $elapsed = sprintf '%f', $c->stats->elapsed;
1579         my $av = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed;
1580         $c->log->info(
1581             "Request took ${elapsed}s ($av/s)\n" . $c->stats->report . "\n" );        
1582     }
1583
1584     return $c->response->status;
1585 }
1586
1587 =head2 $c->finalize_body
1588
1589 Finalizes body.
1590
1591 =cut
1592
1593 sub finalize_body { my $c = shift; $c->engine->finalize_body( $c, @_ ) }
1594
1595 =head2 $c->finalize_cookies
1596
1597 Finalizes cookies.
1598
1599 =cut
1600
1601 sub finalize_cookies { my $c = shift; $c->engine->finalize_cookies( $c, @_ ) }
1602
1603 =head2 $c->finalize_error
1604
1605 Finalizes error.
1606
1607 =cut
1608
1609 sub finalize_error { my $c = shift; $c->engine->finalize_error( $c, @_ ) }
1610
1611 =head2 $c->finalize_headers
1612
1613 Finalizes headers.
1614
1615 =cut
1616
1617 sub finalize_headers {
1618     my $c = shift;
1619
1620     my $response = $c->response; #accessor calls can add up?
1621
1622     # Check if we already finalized headers
1623     return if $response->finalized_headers;
1624
1625     # Handle redirects
1626     if ( my $location = $response->redirect ) {
1627         $c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
1628         $response->header( Location => $location );
1629
1630         if ( !$response->has_body ) {
1631             # Add a default body if none is already present
1632             $response->body(
1633                 qq{<html><body><p>This item has moved <a href="$location">here</a>.</p></body></html>}
1634             );
1635         }
1636     }
1637
1638     # Content-Length
1639     if ( $response->body && !$response->content_length ) {
1640
1641         # get the length from a filehandle
1642         if ( blessed( $response->body ) && $response->body->can('read') )
1643         {
1644             my $stat = stat $response->body;
1645             if ( $stat && $stat->size > 0 ) {
1646                 $response->content_length( $stat->size );
1647             }
1648             else {
1649                 $c->log->warn('Serving filehandle without a content-length');
1650             }
1651         }
1652         else {
1653             # everything should be bytes at this point, but just in case
1654             $response->content_length( bytes::length( $response->body ) );
1655         }
1656     }
1657
1658     # Errors
1659     if ( $response->status =~ /^(1\d\d|[23]04)$/ ) {
1660         $response->headers->remove_header("Content-Length");
1661         $response->body('');
1662     }
1663
1664     $c->finalize_cookies;
1665
1666     $c->engine->finalize_headers( $c, @_ );
1667
1668     # Done
1669     $response->finalized_headers(1);
1670 }
1671
1672 =head2 $c->finalize_output
1673
1674 An alias for finalize_body.
1675
1676 =head2 $c->finalize_read
1677
1678 Finalizes the input after reading is complete.
1679
1680 =cut
1681
1682 sub finalize_read { my $c = shift; $c->engine->finalize_read( $c, @_ ) }
1683
1684 =head2 $c->finalize_uploads
1685
1686 Finalizes uploads. Cleans up any temporary files.
1687
1688 =cut
1689
1690 sub finalize_uploads { my $c = shift; $c->engine->finalize_uploads( $c, @_ ) }
1691
1692 =head2 $c->get_action( $action, $namespace )
1693
1694 Gets an action in a given namespace.
1695
1696 =cut
1697
1698 sub get_action { my $c = shift; $c->dispatcher->get_action(@_) }
1699
1700 =head2 $c->get_actions( $action, $namespace )
1701
1702 Gets all actions of a given name in a namespace and all parent
1703 namespaces.
1704
1705 =cut
1706
1707 sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) }
1708
1709 =head2 $c->handle_request( $class, @arguments )
1710
1711 Called to handle each HTTP request.
1712
1713 =cut
1714
1715 sub handle_request {
1716     my ( $class, @arguments ) = @_;
1717
1718     # Always expect worst case!
1719     my $status = -1;
1720     eval {
1721         if ($class->debug) {
1722             my $secs = time - $START || 1;
1723             my $av = sprintf '%.3f', $COUNT / $secs;
1724             my $time = localtime time;
1725             $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
1726         }
1727
1728         my $c = $class->prepare(@arguments);
1729         $c->dispatch;
1730         $status = $c->finalize;   
1731     };
1732
1733     if ( my $error = $@ ) {
1734         chomp $error;
1735         $class->log->error(qq/Caught exception in engine "$error"/);
1736     }
1737
1738     $COUNT++;
1739     
1740     if(my $coderef = $class->log->can('_flush')){
1741         $class->log->$coderef();
1742     }
1743     return $status;
1744 }
1745
1746 =head2 $c->prepare( @arguments )
1747
1748 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1749 etc.).
1750
1751 =cut
1752
1753 sub prepare {
1754     my ( $class, @arguments ) = @_;
1755
1756     # XXX
1757     # After the app/ctxt split, this should become an attribute based on something passed
1758     # into the application.
1759     $class->context_class( ref $class || $class ) unless $class->context_class;
1760    
1761     my $c = $class->context_class->new({});
1762
1763     # For on-demand data
1764     $c->request->_context($c);
1765     $c->response->_context($c);
1766
1767     #surely this is not the most efficient way to do things...
1768     $c->stats($class->stats_class->new)->enable($c->use_stats);
1769     if ( $c->debug ) {
1770         $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );            
1771     }
1772
1773     #XXX reuse coderef from can
1774     # Allow engine to direct the prepare flow (for POE)
1775     if ( $c->engine->can('prepare') ) {
1776         $c->engine->prepare( $c, @arguments );
1777     }
1778     else {
1779         $c->prepare_request(@arguments);
1780         $c->prepare_connection;
1781         $c->prepare_query_parameters;
1782         $c->prepare_headers;
1783         $c->prepare_cookies;
1784         $c->prepare_path;
1785
1786         # Prepare the body for reading, either by prepare_body
1787         # or the user, if they are using $c->read
1788         $c->prepare_read;
1789         
1790         # Parse the body unless the user wants it on-demand
1791         unless ( $c->config->{parse_on_demand} ) {
1792             $c->prepare_body;
1793         }
1794     }
1795
1796     my $method  = $c->req->method  || '';
1797     my $path    = $c->req->path;
1798     $path       = '/' unless length $path;
1799     my $address = $c->req->address || '';
1800
1801     $c->log->debug(qq/"$method" request for "$path" from "$address"/)
1802       if $c->debug;
1803
1804     $c->prepare_action;
1805
1806     return $c;
1807 }
1808
1809 =head2 $c->prepare_action
1810
1811 Prepares action. See L<Catalyst::Dispatcher>.
1812
1813 =cut
1814
1815 sub prepare_action { my $c = shift; $c->dispatcher->prepare_action( $c, @_ ) }
1816
1817 =head2 $c->prepare_body
1818
1819 Prepares message body.
1820
1821 =cut
1822
1823 sub prepare_body {
1824     my $c = shift;
1825
1826     return if $c->request->_has_body;
1827
1828     # Initialize on-demand data
1829     $c->engine->prepare_body( $c, @_ );
1830     $c->prepare_parameters;
1831     $c->prepare_uploads;
1832
1833     if ( $c->debug && keys %{ $c->req->body_parameters } ) {
1834         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1835         for my $key ( sort keys %{ $c->req->body_parameters } ) {
1836             my $param = $c->req->body_parameters->{$key};
1837             my $value = defined($param) ? $param : '';
1838             $t->row( $key,
1839                 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1840         }
1841         $c->log->debug( "Body Parameters are:\n" . $t->draw );
1842     }
1843 }
1844
1845 =head2 $c->prepare_body_chunk( $chunk )
1846
1847 Prepares a chunk of data before sending it to L<HTTP::Body>.
1848
1849 See L<Catalyst::Engine>.
1850
1851 =cut
1852
1853 sub prepare_body_chunk {
1854     my $c = shift;
1855     $c->engine->prepare_body_chunk( $c, @_ );
1856 }
1857
1858 =head2 $c->prepare_body_parameters
1859
1860 Prepares body parameters.
1861
1862 =cut
1863
1864 sub prepare_body_parameters {
1865     my $c = shift;
1866     $c->engine->prepare_body_parameters( $c, @_ );
1867 }
1868
1869 =head2 $c->prepare_connection
1870
1871 Prepares connection.
1872
1873 =cut
1874
1875 sub prepare_connection {
1876     my $c = shift;
1877     $c->engine->prepare_connection( $c, @_ );
1878 }
1879
1880 =head2 $c->prepare_cookies
1881
1882 Prepares cookies.
1883
1884 =cut
1885
1886 sub prepare_cookies { my $c = shift; $c->engine->prepare_cookies( $c, @_ ) }
1887
1888 =head2 $c->prepare_headers
1889
1890 Prepares headers.
1891
1892 =cut
1893
1894 sub prepare_headers { my $c = shift; $c->engine->prepare_headers( $c, @_ ) }
1895
1896 =head2 $c->prepare_parameters
1897
1898 Prepares parameters.
1899
1900 =cut
1901
1902 sub prepare_parameters {
1903     my $c = shift;
1904     $c->prepare_body_parameters;
1905     $c->engine->prepare_parameters( $c, @_ );
1906 }
1907
1908 =head2 $c->prepare_path
1909
1910 Prepares path and base.
1911
1912 =cut
1913
1914 sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) }
1915
1916 =head2 $c->prepare_query_parameters
1917
1918 Prepares query parameters.
1919
1920 =cut
1921
1922 sub prepare_query_parameters {
1923     my $c = shift;
1924
1925     $c->engine->prepare_query_parameters( $c, @_ );
1926
1927     if ( $c->debug && keys %{ $c->request->query_parameters } ) {
1928         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1929         for my $key ( sort keys %{ $c->req->query_parameters } ) {
1930             my $param = $c->req->query_parameters->{$key};
1931             my $value = defined($param) ? $param : '';
1932             $t->row( $key,
1933                 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1934         }
1935         $c->log->debug( "Query Parameters are:\n" . $t->draw );
1936     }
1937 }
1938
1939 =head2 $c->prepare_read
1940
1941 Prepares the input for reading.
1942
1943 =cut
1944
1945 sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
1946
1947 =head2 $c->prepare_request
1948
1949 Prepares the engine request.
1950
1951 =cut
1952
1953 sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
1954
1955 =head2 $c->prepare_uploads
1956
1957 Prepares uploads.
1958
1959 =cut
1960
1961 sub prepare_uploads {
1962     my $c = shift;
1963
1964     $c->engine->prepare_uploads( $c, @_ );
1965
1966     if ( $c->debug && keys %{ $c->request->uploads } ) {
1967         my $t = Text::SimpleTable->new(
1968             [ 12, 'Parameter' ],
1969             [ 26, 'Filename' ],
1970             [ 18, 'Type' ],
1971             [ 9,  'Size' ]
1972         );
1973         for my $key ( sort keys %{ $c->request->uploads } ) {
1974             my $upload = $c->request->uploads->{$key};
1975             for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
1976                 $t->row( $key, $u->filename, $u->type, $u->size );
1977             }
1978         }
1979         $c->log->debug( "File Uploads are:\n" . $t->draw );
1980     }
1981 }
1982
1983 =head2 $c->prepare_write
1984
1985 Prepares the output for writing.
1986
1987 =cut
1988
1989 sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
1990
1991 =head2 $c->request_class
1992
1993 Returns or sets the request class.
1994
1995 =head2 $c->response_class
1996
1997 Returns or sets the response class.
1998
1999 =head2 $c->read( [$maxlength] )
2000
2001 Reads a chunk of data from the request body. This method is designed to
2002 be used in a while loop, reading C<$maxlength> bytes on every call.
2003 C<$maxlength> defaults to the size of the request if not specified.
2004
2005 You have to set C<< MyApp->config->{parse_on_demand} >> to use this
2006 directly.
2007
2008 Warning: If you use read(), Catalyst will not process the body,
2009 so you will not be able to access POST parameters or file uploads via
2010 $c->request.  You must handle all body parsing yourself.
2011
2012 =cut
2013
2014 sub read { my $c = shift; return $c->engine->read( $c, @_ ) }
2015
2016 =head2 $c->run
2017
2018 Starts the engine.
2019
2020 =cut
2021
2022 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
2023
2024 =head2 $c->set_action( $action, $code, $namespace, $attrs )
2025
2026 Sets an action in a given namespace.
2027
2028 =cut
2029
2030 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
2031
2032 =head2 $c->setup_actions($component)
2033
2034 Sets up actions for a component.
2035
2036 =cut
2037
2038 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
2039
2040 =head2 $c->setup_components
2041
2042 Sets up components. Specify a C<setup_components> config option to pass
2043 additional options directly to L<Module::Pluggable>. To add additional
2044 search paths, specify a key named C<search_extra> as an array
2045 reference. Items in the array beginning with C<::> will have the
2046 application class name prepended to them.
2047
2048 All components found will also have any 
2049 L<Devel::InnerPackage|inner packages> loaded and set up as components.
2050 Note, that modules which are B<not> an I<inner package> of the main
2051 file namespace loaded will not be instantiated as components.
2052
2053 =cut
2054
2055 sub setup_components {
2056     my $class = shift;
2057
2058     my @paths   = qw( ::Controller ::C ::Model ::M ::View ::V );
2059     my $config  = $class->config->{ setup_components };
2060     my $extra   = delete $config->{ search_extra } || [];
2061     
2062     push @paths, @$extra;
2063         
2064     my $locator = Module::Pluggable::Object->new(
2065         search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
2066         %$config
2067     );
2068
2069     my @comps = sort { length $a <=> length $b } $locator->plugins;
2070     my %comps = map { $_ => 1 } @comps;
2071
2072     my $deprecated_component_names = grep { /::[CMV]::/ } @comps;
2073     $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
2074         qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
2075     ) if $deprecated_component_names;
2076
2077     for my $component ( @comps ) {
2078
2079         # We pass ignore_loaded here so that overlay files for (e.g.)
2080         # Model::DBI::Schema sub-classes are loaded - if it's in @comps
2081         # we know M::P::O found a file on disk so this is safe
2082
2083         Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
2084         #Class::MOP::load_class($component);
2085
2086         my $module  = $class->setup_component( $component );
2087         my %modules = (
2088             $component => $module,
2089             map {
2090                 $_ => $class->setup_component( $_ )
2091             } grep { 
2092               not exists $comps{$_}
2093             } Devel::InnerPackage::list_packages( $component )
2094         );
2095         
2096         for my $key ( keys %modules ) {
2097             $class->components->{ $key } = $modules{ $key };
2098         }
2099     }
2100 }
2101
2102 =head2 $c->setup_component
2103
2104 =cut
2105
2106 sub setup_component {
2107     my( $class, $component ) = @_;
2108
2109     unless ( $component->can( 'COMPONENT' ) ) {
2110         return $component;
2111     }
2112
2113     my $suffix = Catalyst::Utils::class2classsuffix( $component );
2114     my $config = $class->config->{ $suffix } || {};
2115
2116     my $instance = eval { $component->COMPONENT( $class, $config ); };
2117
2118     if ( my $error = $@ ) {
2119         chomp $error;
2120         Catalyst::Exception->throw(
2121             message => qq/Couldn't instantiate component "$component", "$error"/
2122         );
2123     }
2124
2125     Catalyst::Exception->throw(
2126         message =>
2127         qq/Couldn't instantiate component "$component", "COMPONENT() didn't return an object-like value"/
2128     ) unless blessed($instance);
2129
2130     return $instance;
2131 }
2132
2133 =head2 $c->setup_dispatcher
2134
2135 Sets up dispatcher.
2136
2137 =cut
2138
2139 sub setup_dispatcher {
2140     my ( $class, $dispatcher ) = @_;
2141
2142     if ($dispatcher) {
2143         $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
2144     }
2145
2146     if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
2147         $dispatcher = 'Catalyst::Dispatcher::' . $env;
2148     }
2149
2150     unless ($dispatcher) {
2151         $dispatcher = $class->dispatcher_class;
2152     }
2153
2154     Class::MOP::load_class($dispatcher);
2155
2156     # dispatcher instance
2157     $class->dispatcher( $dispatcher->new );
2158 }
2159
2160 =head2 $c->setup_engine
2161
2162 Sets up engine.
2163
2164 =cut
2165
2166 sub setup_engine {
2167     my ( $class, $engine ) = @_;
2168
2169     if ($engine) {
2170         $engine = 'Catalyst::Engine::' . $engine;
2171     }
2172
2173     if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
2174         $engine = 'Catalyst::Engine::' . $env;
2175     }
2176
2177     if ( $ENV{MOD_PERL} ) {
2178         my $meta = Class::MOP::get_metaclass_by_name($class);
2179         
2180         # create the apache method
2181         $meta->add_method('apache' => sub { shift->engine->apache });
2182
2183         my ( $software, $version ) =
2184           $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
2185
2186         $version =~ s/_//g;
2187         $version =~ s/(\.[^.]+)\./$1/g;
2188
2189         if ( $software eq 'mod_perl' ) {
2190
2191             if ( !$engine ) {
2192
2193                 if ( $version >= 1.99922 ) {
2194                     $engine = 'Catalyst::Engine::Apache2::MP20';
2195                 }
2196
2197                 elsif ( $version >= 1.9901 ) {
2198                     $engine = 'Catalyst::Engine::Apache2::MP19';
2199                 }
2200
2201                 elsif ( $version >= 1.24 ) {
2202                     $engine = 'Catalyst::Engine::Apache::MP13';
2203                 }
2204
2205                 else {
2206                     Catalyst::Exception->throw( message =>
2207                           qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
2208                 }
2209
2210             }
2211
2212             # install the correct mod_perl handler
2213             if ( $version >= 1.9901 ) {
2214                 *handler = sub  : method {
2215                     shift->handle_request(@_);
2216                 };
2217             }
2218             else {
2219                 *handler = sub ($$) { shift->handle_request(@_) };
2220             }
2221
2222         }
2223
2224         elsif ( $software eq 'Zeus-Perl' ) {
2225             $engine = 'Catalyst::Engine::Zeus';
2226         }
2227
2228         else {
2229             Catalyst::Exception->throw(
2230                 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
2231         }
2232     }
2233
2234     unless ($engine) {
2235         $engine = $class->engine_class;
2236     }
2237
2238     Class::MOP::load_class($engine);
2239
2240     # check for old engines that are no longer compatible
2241     my $old_engine;
2242     if ( $engine->isa('Catalyst::Engine::Apache')
2243         && !Catalyst::Engine::Apache->VERSION )
2244     {
2245         $old_engine = 1;
2246     }
2247
2248     elsif ( $engine->isa('Catalyst::Engine::Server::Base')
2249         && Catalyst::Engine::Server->VERSION le '0.02' )
2250     {
2251         $old_engine = 1;
2252     }
2253
2254     elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
2255         && $engine->VERSION eq '0.01' )
2256     {
2257         $old_engine = 1;
2258     }
2259
2260     elsif ($engine->isa('Catalyst::Engine::Zeus')
2261         && $engine->VERSION eq '0.01' )
2262     {
2263         $old_engine = 1;
2264     }
2265
2266     if ($old_engine) {
2267         Catalyst::Exception->throw( message =>
2268               qq/Engine "$engine" is not supported by this version of Catalyst/
2269         );
2270     }
2271
2272     # engine instance
2273     $class->engine( $engine->new );
2274 }
2275
2276 =head2 $c->setup_home
2277
2278 Sets up the home directory.
2279
2280 =cut
2281
2282 sub setup_home {
2283     my ( $class, $home ) = @_;
2284
2285     if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
2286         $home = $env;
2287     }
2288
2289     $home ||= Catalyst::Utils::home($class);
2290
2291     if ($home) {
2292         #I remember recently being scolded for assigning config values like this
2293         $class->config->{home} ||= $home;
2294         $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
2295     }
2296 }
2297
2298 =head2 $c->setup_log
2299
2300 Sets up log by instantiating a L<Catalyst::Log|Catalyst::Log> object and
2301 passing it to C<log()>. Pass in a comma-delimited list of levels to set the
2302 log to.
2303  
2304 This method also installs a C<debug> method that returns a true value into the
2305 catalyst subclass if the "debug" level is passed in the comma-delimited list,
2306 or if the C<$CATALYST_DEBUG> environment variable is set to a true value.
2307
2308 Note that if the log has already been setup, by either a previous call to
2309 C<setup_log> or by a call such as C<< __PACKAGE__->log( MyLogger->new ) >>,
2310 that this method won't actually set up the log object.
2311
2312 =cut
2313
2314 sub setup_log {
2315     my ( $class, $levels ) = @_;
2316
2317     $levels ||= '';
2318     $levels =~ s/^\s+//;
2319     $levels =~ s/\s+$//;
2320     my %levels = map { $_ => 1 } split /\s*,\s*/, $levels || '';
2321     
2322     unless ( $class->log ) {
2323         $class->log( Catalyst::Log->new(keys %levels) );
2324     }
2325
2326     my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
2327     if ( defined($env_debug) or $levels{debug} ) {
2328         Class::MOP::get_metaclass_by_name($class)->add_method('debug' => sub { 1 });
2329         $class->log->debug('Debug messages enabled');
2330     }
2331 }
2332
2333 =head2 $c->setup_plugins
2334
2335 Sets up plugins.
2336
2337 =cut
2338
2339 =head2 $c->setup_stats
2340
2341 Sets up timing statistics class.
2342
2343 =cut
2344
2345 sub setup_stats {
2346     my ( $class, $stats ) = @_;
2347
2348     Catalyst::Utils::ensure_class_loaded($class->stats_class);
2349
2350     my $env = Catalyst::Utils::env_value( $class, 'STATS' );
2351     if ( defined($env) ? $env : ($stats || $class->debug ) ) {
2352         Class::MOP::get_metaclass_by_name($class)->add_method('use_stats' => sub { 1 });
2353         $class->log->debug('Statistics enabled');
2354     }
2355 }
2356
2357
2358 =head2 $c->registered_plugins 
2359
2360 Returns a sorted list of the plugins which have either been stated in the
2361 import list or which have been added via C<< MyApp->plugin(@args); >>.
2362
2363 If passed a given plugin name, it will report a boolean value indicating
2364 whether or not that plugin is loaded.  A fully qualified name is required if
2365 the plugin name does not begin with C<Catalyst::Plugin::>.
2366
2367  if ($c->registered_plugins('Some::Plugin')) {
2368      ...
2369  }
2370
2371 =cut
2372
2373 {
2374
2375     sub registered_plugins {
2376         my $proto = shift;
2377         return sort keys %{ $proto->_plugins } unless @_;
2378         my $plugin = shift;
2379         return 1 if exists $proto->_plugins->{$plugin};
2380         return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
2381     }
2382
2383     sub _register_plugin {
2384         my ( $proto, $plugin, $instant ) = @_;
2385         my $class = ref $proto || $proto;
2386
2387         # no ignore_loaded here, the plugin may already have been
2388         # defined in memory and we don't want to error on "no file" if so
2389
2390         Class::MOP::load_class( $plugin );
2391
2392         $proto->_plugins->{$plugin} = 1;
2393         unless ($instant) {
2394             no strict 'refs';
2395             if ( my $meta = Class::MOP::get_metaclass_by_name($class) ) {
2396               my @superclasses = ($plugin, $meta->superclasses );
2397               $meta->superclasses(@superclasses);
2398             } else {
2399               unshift @{"$class\::ISA"}, $plugin;
2400             }
2401         }
2402         return $class;
2403     }
2404
2405     sub setup_plugins {
2406         my ( $class, $plugins ) = @_;
2407
2408         $class->_plugins( {} ) unless $class->_plugins;
2409         $plugins ||= [];
2410         for my $plugin ( reverse @$plugins ) {
2411
2412             unless ( $plugin =~ s/\A\+// ) {
2413                 $plugin = "Catalyst::Plugin::$plugin";
2414             }
2415
2416             $class->_register_plugin($plugin);
2417         }
2418     }
2419 }
2420
2421 =head2 $c->stack
2422
2423 Returns an arrayref of the internal execution stack (actions that are
2424 currently executing).
2425
2426 =head2 $c->stats_class
2427
2428 Returns or sets the stats (timing statistics) class.
2429
2430 =head2 $c->use_stats
2431
2432 Returns 1 when stats collection is enabled.  Stats collection is enabled
2433 when the -Stats options is set, debug is on or when the <MYAPP>_STATS
2434 environment variable is set.
2435
2436 Note that this is a static method, not an accessor and should be overloaded
2437 by declaring "sub use_stats { 1 }" in your MyApp.pm, not by calling $c->use_stats(1).
2438
2439 =cut
2440
2441 sub use_stats { 0 }
2442
2443
2444 =head2 $c->write( $data )
2445
2446 Writes $data to the output stream. When using this method directly, you
2447 will need to manually set the C<Content-Length> header to the length of
2448 your output data, if known.
2449
2450 =cut
2451
2452 sub write {
2453     my $c = shift;
2454
2455     # Finalize headers if someone manually writes output
2456     $c->finalize_headers;
2457
2458     return $c->engine->write( $c, @_ );
2459 }
2460
2461 =head2 version
2462
2463 Returns the Catalyst version number. Mostly useful for "powered by"
2464 messages in template systems.
2465
2466 =cut
2467
2468 sub version { return $Catalyst::VERSION }
2469
2470 =head1 INTERNAL ACTIONS
2471
2472 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
2473 C<_ACTION>, and C<_END>. These are by default not shown in the private
2474 action table, but you can make them visible with a config parameter.
2475
2476     MyApp->config->{show_internal_actions} = 1;
2477
2478 =head1 CASE SENSITIVITY
2479
2480 By default Catalyst is not case sensitive, so C<MyApp::C::FOO::Bar> is
2481 mapped to C</foo/bar>. You can activate case sensitivity with a config
2482 parameter.
2483
2484     MyApp->config->{case_sensitive} = 1;
2485
2486 This causes C<MyApp::C::Foo::Bar> to map to C</Foo/Bar>.
2487
2488 =head1 ON-DEMAND PARSER
2489
2490 The request body is usually parsed at the beginning of a request,
2491 but if you want to handle input yourself, you can enable on-demand
2492 parsing with a config parameter.
2493
2494     MyApp->config->{parse_on_demand} = 1;
2495     
2496 =head1 PROXY SUPPORT
2497
2498 Many production servers operate using the common double-server approach,
2499 with a lightweight frontend web server passing requests to a larger
2500 backend server. An application running on the backend server must deal
2501 with two problems: the remote user always appears to be C<127.0.0.1> and
2502 the server's hostname will appear to be C<localhost> regardless of the
2503 virtual host that the user connected through.
2504
2505 Catalyst will automatically detect this situation when you are running
2506 the frontend and backend servers on the same machine. The following
2507 changes are made to the request.
2508
2509     $c->req->address is set to the user's real IP address, as read from 
2510     the HTTP X-Forwarded-For header.
2511     
2512     The host value for $c->req->base and $c->req->uri is set to the real
2513     host, as read from the HTTP X-Forwarded-Host header.
2514
2515 Obviously, your web server must support these headers for this to work.
2516
2517 In a more complex server farm environment where you may have your
2518 frontend proxy server(s) on different machines, you will need to set a
2519 configuration option to tell Catalyst to read the proxied data from the
2520 headers.
2521
2522     MyApp->config->{using_frontend_proxy} = 1;
2523     
2524 If you do not wish to use the proxy support at all, you may set:
2525
2526     MyApp->config->{ignore_frontend_proxy} = 1;
2527
2528 =head1 THREAD SAFETY
2529
2530 Catalyst has been tested under Apache 2's threading C<mpm_worker>,
2531 C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
2532 believe the Catalyst core to be thread-safe.
2533
2534 If you plan to operate in a threaded environment, remember that all other
2535 modules you are using must also be thread-safe. Some modules, most notably
2536 L<DBD::SQLite>, are not thread-safe.
2537
2538 =head1 SUPPORT
2539
2540 IRC:
2541
2542     Join #catalyst on irc.perl.org.
2543
2544 Mailing Lists:
2545
2546     http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
2547     http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
2548
2549 Web:
2550
2551     http://catalyst.perl.org
2552
2553 Wiki:
2554
2555     http://dev.catalyst.perl.org
2556
2557 =head1 SEE ALSO
2558
2559 =head2 L<Task::Catalyst> - All you need to start with Catalyst
2560
2561 =head2 L<Catalyst::Manual> - The Catalyst Manual
2562
2563 =head2 L<Catalyst::Component>, L<Catalyst::Base> - Base classes for components
2564
2565 =head2 L<Catalyst::Engine> - Core engine
2566
2567 =head2 L<Catalyst::Log> - Log class.
2568
2569 =head2 L<Catalyst::Request> - Request object
2570
2571 =head2 L<Catalyst::Response> - Response object
2572
2573 =head2 L<Catalyst::Test> - The test suite.
2574
2575 =head1 PROJECT FOUNDER
2576
2577 sri: Sebastian Riedel <sri@cpan.org>
2578
2579 =head1 CONTRIBUTORS
2580
2581 abw: Andy Wardley
2582
2583 acme: Leon Brocard <leon@astray.com>
2584
2585 Andrew Bramble
2586
2587 Andrew Ford
2588
2589 Andrew Ruthven
2590
2591 andyg: Andy Grundman <andy@hybridized.org>
2592
2593 audreyt: Audrey Tang
2594
2595 bricas: Brian Cassidy <bricas@cpan.org>
2596
2597 Caelum: Rafael Kitover <rkitover@io.com>
2598
2599 chansen: Christian Hansen
2600
2601 chicks: Christopher Hicks
2602
2603 David E. Wheeler
2604
2605 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
2606
2607 Drew Taylor
2608
2609 esskar: Sascha Kiefer
2610
2611 fireartist: Carl Franks <cfranks@cpan.org>
2612
2613 gabb: Danijel Milicevic
2614
2615 Gary Ashton Jones
2616
2617 Geoff Richards
2618
2619 ilmari: Dagfinn Ilmari MannsÃ¥ker <ilmari@ilmari.org>
2620
2621 jcamacho: Juan Camacho
2622
2623 jhannah: Jay Hannah <jay@jays.net>
2624
2625 Jody Belka
2626
2627 Johan Lindstrom
2628
2629 jon: Jon Schutz <jjschutz@cpan.org>
2630
2631 marcus: Marcus Ramberg <mramberg@cpan.org>
2632
2633 miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
2634
2635 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
2636
2637 mugwump: Sam Vilain
2638
2639 naughton: David Naughton
2640
2641 ningu: David Kamholz <dkamholz@cpan.org>
2642
2643 nothingmuch: Yuval Kogman <nothingmuch@woobling.org>
2644
2645 numa: Dan Sully <daniel@cpan.org>
2646
2647 obra: Jesse Vincent
2648
2649 omega: Andreas Marienborg
2650
2651 Oleg Kostyuk <cub.uanic@gmail.com>
2652
2653 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
2654
2655 rafl: Florian Ragwitz <rafl@debian.org>
2656
2657 sky: Arthur Bergman
2658
2659 the_jester: Jesse Sheidlower
2660
2661 t0m: Tomas Doran <bobtfish@bobtfish.net>
2662
2663 Ulf Edvinsson
2664
2665 willert: Sebastian Willert <willert@cpan.org>
2666
2667 =head1 LICENSE
2668
2669 This library is free software, you can redistribute it and/or modify it under
2670 the same terms as Perl itself.
2671
2672 =cut
2673
2674 no Moose;
2675
2676 __PACKAGE__->meta->make_immutable;
2677
2678 1;