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