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