config wins, groditi loses. FUCK YOU FOR SUPPORTING THAT STUPID BEHAVIOR
[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.
757
758 For example:
759
760     $c->path_to( 'db', 'sqlite.db' );
761
762 =cut
763
764 sub path_to {
765     my ( $c, @path ) = @_;
766     my $path = Path::Class::Dir->new( $c->config->{home}, @path );
767     if ( -d $path ) { return $path }
768     else { return Path::Class::File->new( $c->config->{home}, @path ) }
769 }
770
771 =head2 $c->plugin( $name, $class, @args )
772
773 Helper method for plugins. It creates a classdata accessor/mutator and
774 loads and instantiates the given class.
775
776     MyApp->plugin( 'prototype', 'HTML::Prototype' );
777
778     $c->prototype->define_javascript_functions;
779
780 =cut
781
782 sub plugin {
783     my ( $class, $name, $plugin, @args ) = @_;
784     $class->_register_plugin( $plugin, 1 );
785
786     eval { $plugin->import };
787     $class->mk_classdata($name);
788     my $obj;
789     eval { $obj = $plugin->new(@args) };
790
791     if ($@) {
792         Catalyst::Exception->throw( message =>
793               qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
794     }
795
796     $class->$name($obj);
797     $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
798       if $class->debug;
799 }
800
801 =head2 MyApp->setup
802
803 Initializes the dispatcher and engine, loads any plugins, and loads the
804 model, view, and controller components. You may also specify an array
805 of plugins to load here, if you choose to not load them in the C<use
806 Catalyst> line.
807
808     MyApp->setup;
809     MyApp->setup( qw/-Debug/ );
810
811 =cut
812
813 sub setup {
814     my ( $class, @arguments ) = @_;
815     $class->log->warn("Running setup twice is not a good idea.")
816       if ( $class->setup_finished );
817
818     unless ( $class->isa('Catalyst') ) {
819
820         Catalyst::Exception->throw(
821             message => qq/'$class' does not inherit from Catalyst/ );
822     }
823
824     if ( $class->arguments ) {
825         @arguments = ( @arguments, @{ $class->arguments } );
826     }
827
828     # Process options
829     my $flags = {};
830
831     foreach (@arguments) {
832
833         if (/^-Debug$/) {
834             $flags->{log} =
835               ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
836         }
837         elsif (/^-(\w+)=?(.*)$/) {
838             $flags->{ lc $1 } = $2;
839         }
840         else {
841             push @{ $flags->{plugins} }, $_;
842         }
843     }
844
845     $class->setup_home( delete $flags->{home} );
846
847     $class->setup_log( delete $flags->{log} );
848     $class->setup_plugins( delete $flags->{plugins} );
849     $class->setup_dispatcher( delete $flags->{dispatcher} );
850     $class->setup_engine( delete $flags->{engine} );
851     $class->setup_stats( delete $flags->{stats} );
852
853     for my $flag ( sort keys %{$flags} ) {
854
855         if ( my $code = $class->can( 'setup_' . $flag ) ) {
856             &$code( $class, delete $flags->{$flag} );
857         }
858         else {
859             $class->log->warn(qq/Unknown flag "$flag"/);
860         }
861     }
862
863     eval { require Catalyst::Devel; };
864     if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
865         $class->log->warn(<<"EOF");
866 You are running an old script!
867
868   Please update by running (this will overwrite existing files):
869     catalyst.pl -force -scripts $class
870
871   or (this will not overwrite existing files):
872     catalyst.pl -scripts $class
873
874 EOF
875     }
876     
877     if ( $class->debug ) {
878         my @plugins = map { "$_  " . ( $_->VERSION || '' ) } $class->registered_plugins;
879
880         if (@plugins) {
881             my $t = Text::SimpleTable->new(74);
882             $t->row($_) for @plugins;
883             $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" );
884         }
885
886         my $dispatcher = $class->dispatcher;
887         my $engine     = $class->engine;
888         my $home       = $class->config->{home};
889
890         $class->log->debug(qq/Loaded dispatcher "$dispatcher"/);
891         $class->log->debug(qq/Loaded engine "$engine"/);
892
893         $home
894           ? ( -d $home )
895           ? $class->log->debug(qq/Found home "$home"/)
896           : $class->log->debug(qq/Home "$home" doesn't exist/)
897           : $class->log->debug(q/Couldn't find home/);
898     }
899
900     # Call plugins setup
901     {
902         no warnings qw/redefine/;
903         local *setup = sub { };
904         $class->setup;
905     }
906
907     # Initialize our data structure
908     $class->components( {} );
909
910     $class->setup_components;
911
912     if ( $class->debug ) {
913         my $t = Text::SimpleTable->new( [ 63, 'Class' ], [ 8, 'Type' ] );
914         for my $comp ( sort keys %{ $class->components } ) {
915             my $type = ref $class->components->{$comp} ? 'instance' : 'class';
916             $t->row( $comp, $type );
917         }
918         $class->log->debug( "Loaded components:\n" . $t->draw . "\n" )
919           if ( keys %{ $class->components } );
920     }
921
922     # Add our self to components, since we are also a component
923     if( $class->isa('Catalyst::Controller') ){
924       $class->components->{$class} = $class;
925     }
926
927     $class->setup_actions;
928
929     if ( $class->debug ) {
930         my $name = $class->config->{name} || 'Application';
931         $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
932     }
933     $class->log->_flush() if $class->log->can('_flush');
934
935     $class->setup_finished(1);
936 }
937
938 =head2 $c->uri_for( $path, @args?, \%query_values? )
939
940 Merges path with C<< $c->request->base >> for absolute URIs and with
941 C<< $c->namespace >> for relative URIs, then returns a normalized L<URI>
942 object. If any args are passed, they are added at the end of the path.
943 If the last argument to C<uri_for> is a hash reference, it is assumed to
944 contain GET parameter key/value pairs, which will be appended to the URI
945 in standard fashion.
946
947 Note that uri_for is destructive to the passed hashref.  Subsequent calls
948 with the same hashref may have unintended results.
949
950 Instead of C<$path>, you can also optionally pass a C<$action> object
951 which will be resolved to a path using
952 C<< $c->dispatcher->uri_for_action >>; if the first element of
953 C<@args> is an arrayref it is treated as a list of captures to be passed
954 to C<uri_for_action>.
955
956 =cut
957
958 sub uri_for {
959     my ( $c, $path, @args ) = @_;
960
961     if ( Scalar::Util::blessed($path) ) { # action object
962         my $captures = ( scalar @args && ref $args[0] eq 'ARRAY'
963                          ? shift(@args)
964                          : [] );
965         $path = $c->dispatcher->uri_for_action($path, $captures);
966         return undef unless defined($path);
967         $path = '/' if $path eq '';
968     }
969
970     undef($path) if (defined $path && $path eq '');
971
972     my $params =
973       ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
974
975     carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
976     s/([^$URI::uric])/$URI::Escape::escapes{$1}/go for @args;
977
978     unshift(@args, $path);
979
980     unless (defined $path && $path =~ s!^/!!) { # in-place strip
981         my $namespace = $c->namespace;
982         if (defined $path) { # cheesy hack to handle path '../foo'
983            $namespace =~ s{(?:^|/)[^/]+$}{} while $args[0] =~ s{^\.\./}{};
984         }
985         unshift(@args, $namespace || '');
986     }
987     
988     # join args with '/', or a blank string
989     my $args = join('/', grep { defined($_) } @args);
990     $args =~ s/\?/%3F/g; # STUPID STUPID SPECIAL CASE
991     $args =~ s!^/!!;
992     my $base = $c->req->base;
993     my $class = ref($base);
994     $base =~ s{(?<!/)$}{/};
995
996     my $query = '';
997
998     if (my @keys = keys %$params) {
999       # somewhat lifted from URI::_query's query_form
1000       $query = '?'.join('&', map {
1001           s/([;\/?:@&=+,\$\[\]%])/$URI::Escape::escapes{$1}/go;
1002           s/ /+/g;
1003           my $key = $_;
1004           my $val = $params->{$_};
1005           $val = '' unless defined $val;
1006           (map {
1007               $_ = "$_";
1008               utf8::encode( $_ ) if utf8::is_utf8($_);
1009               # using the URI::Escape pattern here so utf8 chars survive
1010               s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
1011               s/ /+/g;
1012               "${key}=$_"; } ( ref $val eq 'ARRAY' ? @$val : $val ));
1013       } @keys);
1014     }
1015
1016     my $res = bless(\"${base}${args}${query}", $class);
1017     $res;
1018 }
1019
1020 =head2 $c->welcome_message
1021
1022 Returns the Catalyst welcome HTML page.
1023
1024 =cut
1025
1026 sub welcome_message {
1027     my $c      = shift;
1028     my $name   = $c->config->{name};
1029     my $logo   = $c->uri_for('/static/images/catalyst_logo.png');
1030     my $prefix = Catalyst::Utils::appprefix( ref $c );
1031     $c->response->content_type('text/html; charset=utf-8');
1032     return <<"EOF";
1033 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1034     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1035 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
1036     <head>
1037     <meta http-equiv="Content-Language" content="en" />
1038     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1039         <title>$name on Catalyst $VERSION</title>
1040         <style type="text/css">
1041             body {
1042                 color: #000;
1043                 background-color: #eee;
1044             }
1045             div#content {
1046                 width: 640px;
1047                 margin-left: auto;
1048                 margin-right: auto;
1049                 margin-top: 10px;
1050                 margin-bottom: 10px;
1051                 text-align: left;
1052                 background-color: #ccc;
1053                 border: 1px solid #aaa;
1054             }
1055             p, h1, h2 {
1056                 margin-left: 20px;
1057                 margin-right: 20px;
1058                 font-family: verdana, tahoma, sans-serif;
1059             }
1060             a {
1061                 font-family: verdana, tahoma, sans-serif;
1062             }
1063             :link, :visited {
1064                     text-decoration: none;
1065                     color: #b00;
1066                     border-bottom: 1px dotted #bbb;
1067             }
1068             :link:hover, :visited:hover {
1069                     color: #555;
1070             }
1071             div#topbar {
1072                 margin: 0px;
1073             }
1074             pre {
1075                 margin: 10px;
1076                 padding: 8px;
1077             }
1078             div#answers {
1079                 padding: 8px;
1080                 margin: 10px;
1081                 background-color: #fff;
1082                 border: 1px solid #aaa;
1083             }
1084             h1 {
1085                 font-size: 0.9em;
1086                 font-weight: normal;
1087                 text-align: center;
1088             }
1089             h2 {
1090                 font-size: 1.0em;
1091             }
1092             p {
1093                 font-size: 0.9em;
1094             }
1095             p img {
1096                 float: right;
1097                 margin-left: 10px;
1098             }
1099             span#appname {
1100                 font-weight: bold;
1101                 font-size: 1.6em;
1102             }
1103         </style>
1104     </head>
1105     <body>
1106         <div id="content">
1107             <div id="topbar">
1108                 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
1109                     $VERSION</h1>
1110              </div>
1111              <div id="answers">
1112                  <p>
1113                  <img src="$logo" alt="Catalyst Logo" />
1114                  </p>
1115                  <p>Welcome to the  world of Catalyst.
1116                     This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
1117                     framework will make web development something you had
1118                     never expected it to be: Fun, rewarding, and quick.</p>
1119                  <h2>What to do now?</h2>
1120                  <p>That really depends  on what <b>you</b> want to do.
1121                     We do, however, provide you with a few starting points.</p>
1122                  <p>If you want to jump right into web development with Catalyst
1123                     you might want want to start with a tutorial.</p>
1124 <pre>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
1125 </pre>
1126 <p>Afterwards you can go on to check out a more complete look at our features.</p>
1127 <pre>
1128 <code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
1129 <!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
1130 </code></pre>
1131                  <h2>What to do next?</h2>
1132                  <p>Next it's time to write an actual application. Use the
1133                     helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&amp;mode=all">controllers</a>,
1134                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&amp;mode=all">models</a>, and
1135                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&amp;mode=all">views</a>;
1136                     they can save you a lot of work.</p>
1137                     <pre><code>script/${prefix}_create.pl -help</code></pre>
1138                     <p>Also, be sure to check out the vast and growing
1139                     collection of <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3APlugin%3A%3A&amp;mode=all">plugins for Catalyst on CPAN</a>;
1140                     you are likely to find what you need there.
1141                     </p>
1142
1143                  <h2>Need help?</h2>
1144                  <p>Catalyst has a very active community. Here are the main places to
1145                     get in touch with us.</p>
1146                  <ul>
1147                      <li>
1148                          <a href="http://dev.catalyst.perl.org">Wiki</a>
1149                      </li>
1150                      <li>
1151                          <a href="http://lists.rawmode.org/mailman/listinfo/catalyst">Mailing-List</a>
1152                      </li>
1153                      <li>
1154                          <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
1155                      </li>
1156                  </ul>
1157                  <h2>In conclusion</h2>
1158                  <p>The Catalyst team hopes you will enjoy using Catalyst as much 
1159                     as we enjoyed making it. Please contact us if you have ideas
1160                     for improvement or other feedback.</p>
1161              </div>
1162          </div>
1163     </body>
1164 </html>
1165 EOF
1166 }
1167
1168 =head1 INTERNAL METHODS
1169
1170 These methods are not meant to be used by end users.
1171
1172 =head2 $c->components
1173
1174 Returns a hash of components.
1175
1176 =head2 $c->context_class
1177
1178 Returns or sets the context class.
1179
1180 =head2 $c->counter
1181
1182 Returns a hashref containing coderefs and execution counts (needed for
1183 deep recursion detection).
1184
1185 =head2 $c->depth
1186
1187 Returns the number of actions on the current internal execution stack.
1188
1189 =head2 $c->dispatch
1190
1191 Dispatches a request to actions.
1192
1193 =cut
1194
1195 sub dispatch { my $c = shift; $c->dispatcher->dispatch( $c, @_ ) }
1196
1197 =head2 $c->dispatcher_class
1198
1199 Returns or sets the dispatcher class.
1200
1201 =head2 $c->dump_these
1202
1203 Returns a list of 2-element array references (name, structure) pairs
1204 that will be dumped on the error page in debug mode.
1205
1206 =cut
1207
1208 sub dump_these {
1209     my $c = shift;
1210     [ Request => $c->req ], 
1211     [ Response => $c->res ], 
1212     [ Stash => $c->stash ],
1213     [ Config => $c->config ];
1214 }
1215
1216 =head2 $c->engine_class
1217
1218 Returns or sets the engine class.
1219
1220 =head2 $c->execute( $class, $coderef )
1221
1222 Execute a coderef in given class and catch exceptions. Errors are available
1223 via $c->error.
1224
1225 =cut
1226
1227 sub execute {
1228     my ( $c, $class, $code ) = @_;
1229     $class = $c->component($class) || $class;
1230     $c->state(0);
1231
1232     if ( $c->depth >= $RECURSION ) {
1233         my $action = $code->reverse();
1234         $action = "/$action" unless $action =~ /->/;
1235         my $error = qq/Deep recursion detected calling "${action}"/;
1236         $c->log->error($error);
1237         $c->error($error);
1238         $c->state(0);
1239         return $c->state;
1240     }
1241
1242     my $stats_info = $c->_stats_start_execute( $code ) if $c->use_stats;
1243
1244     push( @{ $c->stack }, $code );
1245     
1246     eval { $c->state( $code->execute( $class, $c, @{ $c->req->args } ) || 0 ) };
1247
1248     $c->_stats_finish_execute( $stats_info ) if $c->use_stats and $stats_info;
1249     
1250     my $last = pop( @{ $c->stack } );
1251
1252     if ( my $error = $@ ) {
1253         if ( !ref($error) and $error eq $DETACH ) { die $DETACH if $c->depth > 1 }
1254         else {
1255             unless ( ref $error ) {
1256                 no warnings 'uninitialized';
1257                 chomp $error;
1258                 my $class = $last->class;
1259                 my $name  = $last->name;
1260                 $error = qq/Caught exception in $class->$name "$error"/;
1261             }
1262             $c->error($error);
1263             $c->state(0);
1264         }
1265     }
1266     return $c->state;
1267 }
1268
1269 sub _stats_start_execute {
1270     my ( $c, $code ) = @_;
1271
1272     return if ( ( $code->name =~ /^_.*/ )
1273         && ( !$c->config->{show_internal_actions} ) );
1274
1275     my $action_name = $code->reverse();
1276     $c->counter->{$action_name}++;
1277
1278     my $action = $action_name;
1279     $action = "/$action" unless $action =~ /->/;
1280
1281     # determine if the call was the result of a forward
1282     # this is done by walking up the call stack and looking for a calling
1283     # sub of Catalyst::forward before the eval
1284     my $callsub = q{};
1285     for my $index ( 2 .. 11 ) {
1286         last
1287         if ( ( caller($index) )[0] eq 'Catalyst'
1288             && ( caller($index) )[3] eq '(eval)' );
1289
1290         if ( ( caller($index) )[3] =~ /forward$/ ) {
1291             $callsub = ( caller($index) )[3];
1292             $action  = "-> $action";
1293             last;
1294         }
1295     }
1296
1297     my $uid = $action_name . $c->counter->{$action_name};
1298
1299     # is this a root-level call or a forwarded call?
1300     if ( $callsub =~ /forward$/ ) {
1301
1302         # forward, locate the caller
1303         if ( my $parent = $c->stack->[-1] ) {
1304             $c->stats->profile(
1305                 begin  => $action, 
1306                 parent => "$parent" . $c->counter->{"$parent"},
1307                 uid    => $uid,
1308             );
1309         }
1310         else {
1311
1312             # forward with no caller may come from a plugin
1313             $c->stats->profile(
1314                 begin => $action,
1315                 uid   => $uid,
1316             );
1317         }
1318     }
1319     else {
1320         
1321         # root-level call
1322         $c->stats->profile(
1323             begin => $action,
1324             uid   => $uid,
1325         );
1326     }
1327     return $action;
1328
1329 }
1330
1331 sub _stats_finish_execute {
1332     my ( $c, $info ) = @_;
1333     $c->stats->profile( end => $info );
1334 }
1335
1336 =head2 $c->_localize_fields( sub { }, \%keys );
1337
1338 =cut
1339
1340 #Why does this exist? This is no longer safe and WILL NOT WORK.
1341 # it doesnt seem to be used anywhere. can we remove it?
1342 sub _localize_fields {
1343     my ( $c, $localized, $code ) = ( @_ );
1344
1345     my $request = delete $localized->{request} || {};
1346     my $response = delete $localized->{response} || {};
1347     
1348     local @{ $c }{ keys %$localized } = values %$localized;
1349     local @{ $c->request }{ keys %$request } = values %$request;
1350     local @{ $c->response }{ keys %$response } = values %$response;
1351
1352     $code->();
1353 }
1354
1355 =head2 $c->finalize
1356
1357 Finalizes the request.
1358
1359 =cut
1360
1361 sub finalize {
1362     my $c = shift;
1363
1364     for my $error ( @{ $c->error } ) {
1365         $c->log->error($error);
1366     }
1367
1368     # Allow engine to handle finalize flow (for POE)
1369     my $engine = $c->engine;
1370     if ( my $code = $engine->can('finalize') ) {
1371         $engine->$code($c);
1372     }
1373     else {
1374
1375         $c->finalize_uploads;
1376
1377         # Error
1378         if ( $#{ $c->error } >= 0 ) {
1379             $c->finalize_error;
1380         }
1381
1382         $c->finalize_headers;
1383
1384         # HEAD request
1385         if ( $c->request->method eq 'HEAD' ) {
1386             $c->response->body('');
1387         }
1388
1389         $c->finalize_body;
1390     }
1391     
1392     if ($c->use_stats) {        
1393         my $elapsed = sprintf '%f', $c->stats->elapsed;
1394         my $av = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed;
1395         $c->log->info(
1396             "Request took ${elapsed}s ($av/s)\n" . $c->stats->report . "\n" );        
1397     }
1398
1399     return $c->response->status;
1400 }
1401
1402 =head2 $c->finalize_body
1403
1404 Finalizes body.
1405
1406 =cut
1407
1408 sub finalize_body { my $c = shift; $c->engine->finalize_body( $c, @_ ) }
1409
1410 =head2 $c->finalize_cookies
1411
1412 Finalizes cookies.
1413
1414 =cut
1415
1416 sub finalize_cookies { my $c = shift; $c->engine->finalize_cookies( $c, @_ ) }
1417
1418 =head2 $c->finalize_error
1419
1420 Finalizes error.
1421
1422 =cut
1423
1424 sub finalize_error { my $c = shift; $c->engine->finalize_error( $c, @_ ) }
1425
1426 =head2 $c->finalize_headers
1427
1428 Finalizes headers.
1429
1430 =cut
1431
1432 sub finalize_headers {
1433     my $c = shift;
1434
1435     my $response = $c->response; #accessor calls can add up?
1436
1437     # Check if we already finalized headers
1438     return if $response->finalized_headers;
1439
1440     # Handle redirects
1441     if ( my $location = $response->redirect ) {
1442         $c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
1443         $response->header( Location => $location );
1444
1445         #Moose TODO: we should probably be using a predicate method here ?
1446         if ( !$response->body ) {
1447             # Add a default body if none is already present
1448             $response->body(
1449                 qq{<html><body><p>This item has moved <a href="$location">here</a>.</p></body></html>}
1450             );
1451         }
1452     }
1453
1454     # Content-Length
1455     if ( $response->body && !$response->content_length ) {
1456
1457         # get the length from a filehandle
1458         if ( blessed( $response->body ) && $response->body->can('read') )
1459         {
1460             my $stat = stat $response->body;
1461             if ( $stat && $stat->size > 0 ) {
1462                 $response->content_length( $stat->size );
1463             }
1464             else {
1465                 $c->log->warn('Serving filehandle without a content-length');
1466             }
1467         }
1468         else {
1469             # everything should be bytes at this point, but just in case
1470             $response->content_length( bytes::length( $response->body ) );
1471         }
1472     }
1473
1474     # Errors
1475     if ( $response->status =~ /^(1\d\d|[23]04)$/ ) {
1476         $response->headers->remove_header("Content-Length");
1477         $response->body('');
1478     }
1479
1480     $c->finalize_cookies;
1481
1482     $c->engine->finalize_headers( $c, @_ );
1483
1484     # Done
1485     $response->finalized_headers(1);
1486 }
1487
1488 =head2 $c->finalize_output
1489
1490 An alias for finalize_body.
1491
1492 =head2 $c->finalize_read
1493
1494 Finalizes the input after reading is complete.
1495
1496 =cut
1497
1498 sub finalize_read { my $c = shift; $c->engine->finalize_read( $c, @_ ) }
1499
1500 =head2 $c->finalize_uploads
1501
1502 Finalizes uploads. Cleans up any temporary files.
1503
1504 =cut
1505
1506 sub finalize_uploads { my $c = shift; $c->engine->finalize_uploads( $c, @_ ) }
1507
1508 =head2 $c->get_action( $action, $namespace )
1509
1510 Gets an action in a given namespace.
1511
1512 =cut
1513
1514 sub get_action { my $c = shift; $c->dispatcher->get_action(@_) }
1515
1516 =head2 $c->get_actions( $action, $namespace )
1517
1518 Gets all actions of a given name in a namespace and all parent
1519 namespaces.
1520
1521 =cut
1522
1523 sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) }
1524
1525 =head2 $c->handle_request( $class, @arguments )
1526
1527 Called to handle each HTTP request.
1528
1529 =cut
1530
1531 sub handle_request {
1532     my ( $class, @arguments ) = @_;
1533
1534     # Always expect worst case!
1535     my $status = -1;
1536     eval {
1537         if ($class->debug) {
1538             my $secs = time - $START || 1;
1539             my $av = sprintf '%.3f', $COUNT / $secs;
1540             my $time = localtime time;
1541             $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
1542         }
1543
1544         my $c = $class->prepare(@arguments);
1545         $c->dispatch;
1546         $status = $c->finalize;   
1547     };
1548
1549     if ( my $error = $@ ) {
1550         chomp $error;
1551         $class->log->error(qq/Caught exception in engine "$error"/);
1552     }
1553
1554     $COUNT++;
1555     
1556     if(my $coderef = $class->log->can('_flush')){
1557         $class->log->$coderef();
1558     }
1559     return $status;
1560 }
1561
1562 =head2 $c->prepare( @arguments )
1563
1564 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1565 etc.).
1566
1567 =cut
1568
1569 sub prepare {
1570     my ( $class, @arguments ) = @_;
1571
1572     # XXX
1573     # After the app/ctxt split, this should become an attribute based on something passed
1574     # into the application.
1575     $class->context_class( ref $class || $class ) unless $class->context_class;
1576    
1577     my $c = $class->context_class->new({});
1578
1579     # For on-demand data
1580     $c->request->_context($c);
1581     $c->response->_context($c);
1582
1583     #surely this is not the most efficient way to do things...
1584     $c->stats($class->stats_class->new)->enable($c->use_stats);
1585     if ( $c->debug ) {
1586         $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );            
1587     }
1588
1589     #XXX reuse coderef from can
1590     # Allow engine to direct the prepare flow (for POE)
1591     if ( $c->engine->can('prepare') ) {
1592         $c->engine->prepare( $c, @arguments );
1593     }
1594     else {
1595         $c->prepare_request(@arguments);
1596         $c->prepare_connection;
1597         $c->prepare_query_parameters;
1598         $c->prepare_headers;
1599         $c->prepare_cookies;
1600         $c->prepare_path;
1601
1602         # Prepare the body for reading, either by prepare_body
1603         # or the user, if they are using $c->read
1604         $c->prepare_read;
1605         
1606         # Parse the body unless the user wants it on-demand
1607         unless ( $c->config->{parse_on_demand} ) {
1608             $c->prepare_body;
1609         }
1610     }
1611
1612     my $method  = $c->req->method  || '';
1613     my $path    = $c->req->path    || '/';
1614     my $address = $c->req->address || '';
1615
1616     $c->log->debug(qq/"$method" request for "$path" from "$address"/)
1617       if $c->debug;
1618
1619     $c->prepare_action;
1620
1621     return $c;
1622 }
1623
1624 =head2 $c->prepare_action
1625
1626 Prepares action. See L<Catalyst::Dispatcher>.
1627
1628 =cut
1629
1630 sub prepare_action { my $c = shift; $c->dispatcher->prepare_action( $c, @_ ) }
1631
1632 =head2 $c->prepare_body
1633
1634 Prepares message body.
1635
1636 =cut
1637
1638 sub prepare_body {
1639     my $c = shift;
1640
1641     #Moose TODO: what is  _body ??
1642     # Do we run for the first time?
1643     return if defined $c->request->{_body};
1644
1645     # Initialize on-demand data
1646     $c->engine->prepare_body( $c, @_ );
1647     $c->prepare_parameters;
1648     $c->prepare_uploads;
1649
1650     if ( $c->debug && keys %{ $c->req->body_parameters } ) {
1651         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1652         for my $key ( sort keys %{ $c->req->body_parameters } ) {
1653             my $param = $c->req->body_parameters->{$key};
1654             my $value = defined($param) ? $param : '';
1655             $t->row( $key,
1656                 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1657         }
1658         $c->log->debug( "Body Parameters are:\n" . $t->draw );
1659     }
1660 }
1661
1662 =head2 $c->prepare_body_chunk( $chunk )
1663
1664 Prepares a chunk of data before sending it to L<HTTP::Body>.
1665
1666 See L<Catalyst::Engine>.
1667
1668 =cut
1669
1670 sub prepare_body_chunk {
1671     my $c = shift;
1672     $c->engine->prepare_body_chunk( $c, @_ );
1673 }
1674
1675 =head2 $c->prepare_body_parameters
1676
1677 Prepares body parameters.
1678
1679 =cut
1680
1681 sub prepare_body_parameters {
1682     my $c = shift;
1683     $c->engine->prepare_body_parameters( $c, @_ );
1684 }
1685
1686 =head2 $c->prepare_connection
1687
1688 Prepares connection.
1689
1690 =cut
1691
1692 sub prepare_connection {
1693     my $c = shift;
1694     $c->engine->prepare_connection( $c, @_ );
1695 }
1696
1697 =head2 $c->prepare_cookies
1698
1699 Prepares cookies.
1700
1701 =cut
1702
1703 sub prepare_cookies { my $c = shift; $c->engine->prepare_cookies( $c, @_ ) }
1704
1705 =head2 $c->prepare_headers
1706
1707 Prepares headers.
1708
1709 =cut
1710
1711 sub prepare_headers { my $c = shift; $c->engine->prepare_headers( $c, @_ ) }
1712
1713 =head2 $c->prepare_parameters
1714
1715 Prepares parameters.
1716
1717 =cut
1718
1719 sub prepare_parameters {
1720     my $c = shift;
1721     $c->prepare_body_parameters;
1722     $c->engine->prepare_parameters( $c, @_ );
1723 }
1724
1725 =head2 $c->prepare_path
1726
1727 Prepares path and base.
1728
1729 =cut
1730
1731 sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) }
1732
1733 =head2 $c->prepare_query_parameters
1734
1735 Prepares query parameters.
1736
1737 =cut
1738
1739 sub prepare_query_parameters {
1740     my $c = shift;
1741
1742     $c->engine->prepare_query_parameters( $c, @_ );
1743
1744     if ( $c->debug && keys %{ $c->request->query_parameters } ) {
1745         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1746         for my $key ( sort keys %{ $c->req->query_parameters } ) {
1747             my $param = $c->req->query_parameters->{$key};
1748             my $value = defined($param) ? $param : '';
1749             $t->row( $key,
1750                 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1751         }
1752         $c->log->debug( "Query Parameters are:\n" . $t->draw );
1753     }
1754 }
1755
1756 =head2 $c->prepare_read
1757
1758 Prepares the input for reading.
1759
1760 =cut
1761
1762 sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
1763
1764 =head2 $c->prepare_request
1765
1766 Prepares the engine request.
1767
1768 =cut
1769
1770 sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
1771
1772 =head2 $c->prepare_uploads
1773
1774 Prepares uploads.
1775
1776 =cut
1777
1778 sub prepare_uploads {
1779     my $c = shift;
1780
1781     $c->engine->prepare_uploads( $c, @_ );
1782
1783     if ( $c->debug && keys %{ $c->request->uploads } ) {
1784         my $t = Text::SimpleTable->new(
1785             [ 12, 'Parameter' ],
1786             [ 26, 'Filename' ],
1787             [ 18, 'Type' ],
1788             [ 9,  'Size' ]
1789         );
1790         for my $key ( sort keys %{ $c->request->uploads } ) {
1791             my $upload = $c->request->uploads->{$key};
1792             for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
1793                 $t->row( $key, $u->filename, $u->type, $u->size );
1794             }
1795         }
1796         $c->log->debug( "File Uploads are:\n" . $t->draw );
1797     }
1798 }
1799
1800 =head2 $c->prepare_write
1801
1802 Prepares the output for writing.
1803
1804 =cut
1805
1806 sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
1807
1808 =head2 $c->request_class
1809
1810 Returns or sets the request class.
1811
1812 =head2 $c->response_class
1813
1814 Returns or sets the response class.
1815
1816 =head2 $c->read( [$maxlength] )
1817
1818 Reads a chunk of data from the request body. This method is designed to
1819 be used in a while loop, reading C<$maxlength> bytes on every call.
1820 C<$maxlength> defaults to the size of the request if not specified.
1821
1822 You have to set C<< MyApp->config->{parse_on_demand} >> to use this
1823 directly.
1824
1825 Warning: If you use read(), Catalyst will not process the body,
1826 so you will not be able to access POST parameters or file uploads via
1827 $c->request.  You must handle all body parsing yourself.
1828
1829 =cut
1830
1831 sub read { my $c = shift; return $c->engine->read( $c, @_ ) }
1832
1833 =head2 $c->run
1834
1835 Starts the engine.
1836
1837 =cut
1838
1839 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
1840
1841 =head2 $c->set_action( $action, $code, $namespace, $attrs )
1842
1843 Sets an action in a given namespace.
1844
1845 =cut
1846
1847 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
1848
1849 =head2 $c->setup_actions($component)
1850
1851 Sets up actions for a component.
1852
1853 =cut
1854
1855 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
1856
1857 =head2 $c->setup_components
1858
1859 Sets up components. Specify a C<setup_components> config option to pass
1860 additional options directly to L<Module::Pluggable>. To add additional
1861 search paths, specify a key named C<search_extra> as an array
1862 reference. Items in the array beginning with C<::> will have the
1863 application class name prepended to them.
1864
1865 =cut
1866
1867 sub setup_components {
1868     my $class = shift;
1869
1870     my @paths   = qw( ::Controller ::C ::Model ::M ::View ::V );
1871     my $config  = $class->config->{ setup_components };
1872     my $extra   = delete $config->{ search_extra } || [];
1873     
1874     push @paths, @$extra;
1875         
1876     my $locator = Module::Pluggable::Object->new(
1877         search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
1878         %$config
1879     );
1880
1881     my @comps = sort { length $a <=> length $b } $locator->plugins;
1882     my %comps = map { $_ => 1 } @comps;
1883     
1884     for my $component ( @comps ) {
1885
1886         # We pass ignore_loaded here so that overlay files for (e.g.)
1887         # Model::DBI::Schema sub-classes are loaded - if it's in @comps
1888         # we know M::P::O found a file on disk so this is safe
1889
1890         Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
1891         #Class::MOP::load_class($component);
1892
1893         my $module  = $class->setup_component( $component );
1894         my %modules = (
1895             $component => $module,
1896             map {
1897                 $_ => $class->setup_component( $_ )
1898             } grep { 
1899               not exists $comps{$_}
1900             } Devel::InnerPackage::list_packages( $component )
1901         );
1902         
1903         for my $key ( keys %modules ) {
1904             $class->components->{ $key } = $modules{ $key };
1905         }
1906     }
1907 }
1908
1909 =head2 $c->setup_component
1910
1911 =cut
1912
1913 sub setup_component {
1914     my( $class, $component ) = @_;
1915
1916     unless ( $component->can( 'COMPONENT' ) ) {
1917         return $component;
1918     }
1919
1920     my $suffix = Catalyst::Utils::class2classsuffix( $component );
1921     my $config = $class->config->{ $suffix } || {};
1922
1923     my $instance = eval { $component->COMPONENT( $class, $config ); };
1924
1925     if ( my $error = $@ ) {
1926         chomp $error;
1927         Catalyst::Exception->throw(
1928             message => qq/Couldn't instantiate component "$component", "$error"/
1929         );
1930     }
1931
1932     Catalyst::Exception->throw(
1933         message =>
1934         qq/Couldn't instantiate component "$component", "COMPONENT() didn't return an object-like value"/
1935     ) unless blessed($instance);
1936
1937     return $instance;
1938 }
1939
1940 =head2 $c->setup_dispatcher
1941
1942 Sets up dispatcher.
1943
1944 =cut
1945
1946 sub setup_dispatcher {
1947     my ( $class, $dispatcher ) = @_;
1948
1949     if ($dispatcher) {
1950         $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
1951     }
1952
1953     if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
1954         $dispatcher = 'Catalyst::Dispatcher::' . $env;
1955     }
1956
1957     unless ($dispatcher) {
1958         $dispatcher = $class->dispatcher_class;
1959     }
1960
1961     Class::MOP::load_class($dispatcher);
1962
1963     # dispatcher instance
1964     $class->dispatcher( $dispatcher->new );
1965 }
1966
1967 =head2 $c->setup_engine
1968
1969 Sets up engine.
1970
1971 =cut
1972
1973 sub setup_engine {
1974     my ( $class, $engine ) = @_;
1975
1976     if ($engine) {
1977         $engine = 'Catalyst::Engine::' . $engine;
1978     }
1979
1980     if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
1981         $engine = 'Catalyst::Engine::' . $env;
1982     }
1983
1984     if ( $ENV{MOD_PERL} ) {
1985
1986         # create the apache method
1987         $class->meta->add_method('apache' => sub { shift->engine->apache });
1988
1989         my ( $software, $version ) =
1990           $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
1991
1992         $version =~ s/_//g;
1993         $version =~ s/(\.[^.]+)\./$1/g;
1994
1995         if ( $software eq 'mod_perl' ) {
1996
1997             if ( !$engine ) {
1998
1999                 if ( $version >= 1.99922 ) {
2000                     $engine = 'Catalyst::Engine::Apache2::MP20';
2001                 }
2002
2003                 elsif ( $version >= 1.9901 ) {
2004                     $engine = 'Catalyst::Engine::Apache2::MP19';
2005                 }
2006
2007                 elsif ( $version >= 1.24 ) {
2008                     $engine = 'Catalyst::Engine::Apache::MP13';
2009                 }
2010
2011                 else {
2012                     Catalyst::Exception->throw( message =>
2013                           qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
2014                 }
2015
2016             }
2017
2018             # install the correct mod_perl handler
2019             if ( $version >= 1.9901 ) {
2020                 *handler = sub  : method {
2021                     shift->handle_request(@_);
2022                 };
2023             }
2024             else {
2025                 *handler = sub ($$) { shift->handle_request(@_) };
2026             }
2027
2028         }
2029
2030         elsif ( $software eq 'Zeus-Perl' ) {
2031             $engine = 'Catalyst::Engine::Zeus';
2032         }
2033
2034         else {
2035             Catalyst::Exception->throw(
2036                 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
2037         }
2038     }
2039
2040     unless ($engine) {
2041         $engine = $class->engine_class;
2042     }
2043
2044     Class::MOP::load_class($engine);
2045     #unless (Class::Inspector->loaded($engine)) {
2046     #    require Class::Inspector->filename($engine);
2047     #}
2048
2049     # check for old engines that are no longer compatible
2050     my $old_engine;
2051     if ( $engine->isa('Catalyst::Engine::Apache')
2052         && !Catalyst::Engine::Apache->VERSION )
2053     {
2054         $old_engine = 1;
2055     }
2056
2057     elsif ( $engine->isa('Catalyst::Engine::Server::Base')
2058         && Catalyst::Engine::Server->VERSION le '0.02' )
2059     {
2060         $old_engine = 1;
2061     }
2062
2063     elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
2064         && $engine->VERSION eq '0.01' )
2065     {
2066         $old_engine = 1;
2067     }
2068
2069     elsif ($engine->isa('Catalyst::Engine::Zeus')
2070         && $engine->VERSION eq '0.01' )
2071     {
2072         $old_engine = 1;
2073     }
2074
2075     if ($old_engine) {
2076         Catalyst::Exception->throw( message =>
2077               qq/Engine "$engine" is not supported by this version of Catalyst/
2078         );
2079     }
2080
2081     # engine instance
2082     $class->engine( $engine->new );
2083 }
2084
2085 =head2 $c->setup_home
2086
2087 Sets up the home directory.
2088
2089 =cut
2090
2091 sub setup_home {
2092     my ( $class, $home ) = @_;
2093
2094     if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
2095         $home = $env;
2096     }
2097
2098     $home ||= Catalyst::Utils::home($class);
2099
2100     if ($home) {
2101         #I remember recently being scolded for assigning config values like this
2102         $class->config->{home} ||= $home;
2103         $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
2104     }
2105 }
2106
2107 =head2 $c->setup_log
2108
2109 Sets up log.
2110
2111 =cut
2112
2113 sub setup_log {
2114     my ( $class, $debug ) = @_;
2115
2116     unless ( $class->log ) {
2117         $class->log( Catalyst::Log->new );
2118     }
2119
2120     my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
2121     if ( defined($env_debug) ? $env_debug : $debug ) {
2122         $class->meta->add_method('debug' => sub { 1 });
2123         $class->log->debug('Debug messages enabled');
2124     }
2125 }
2126
2127 =head2 $c->setup_plugins
2128
2129 Sets up plugins.
2130
2131 =cut
2132
2133 =head2 $c->setup_stats
2134
2135 Sets up timing statistics class.
2136
2137 =cut
2138
2139 sub setup_stats {
2140     my ( $class, $stats ) = @_;
2141
2142     Catalyst::Utils::ensure_class_loaded($class->stats_class);
2143
2144     my $env = Catalyst::Utils::env_value( $class, 'STATS' );
2145     if ( defined($env) ? $env : ($stats || $class->debug ) ) {
2146         $class->meta->add_method('use_stats' => sub { 1 });
2147         $class->log->debug('Statistics enabled');
2148     }
2149 }
2150
2151
2152 =head2 $c->registered_plugins 
2153
2154 Returns a sorted list of the plugins which have either been stated in the
2155 import list or which have been added via C<< MyApp->plugin(@args); >>.
2156
2157 If passed a given plugin name, it will report a boolean value indicating
2158 whether or not that plugin is loaded.  A fully qualified name is required if
2159 the plugin name does not begin with C<Catalyst::Plugin::>.
2160
2161  if ($c->registered_plugins('Some::Plugin')) {
2162      ...
2163  }
2164
2165 =cut
2166
2167 {
2168
2169     sub registered_plugins {
2170         my $proto = shift;
2171         return sort keys %{ $proto->_plugins } unless @_;
2172         my $plugin = shift;
2173         return 1 if exists $proto->_plugins->{$plugin};
2174         return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
2175     }
2176
2177     sub _register_plugin {
2178         my ( $proto, $plugin, $instant ) = @_;
2179         my $class = ref $proto || $proto;
2180
2181         # no ignore_loaded here, the plugin may already have been
2182         # defined in memory and we don't want to error on "no file" if so
2183
2184         Class::MOP::load_class( $plugin );
2185
2186         $proto->_plugins->{$plugin} = 1;
2187         unless ($instant) {
2188             no strict 'refs';
2189             if( $class->can('meta') ){
2190               my @superclasses = ($plugin, $class->meta->superclasses );
2191               $class->meta->superclasses(@superclasses);
2192             } else {
2193               unshift @{"$class\::ISA"}, $plugin;
2194             }
2195         }
2196         return $class;
2197     }
2198
2199     sub setup_plugins {
2200         my ( $class, $plugins ) = @_;
2201
2202         $class->_plugins( {} ) unless $class->_plugins;
2203         $plugins ||= [];
2204         for my $plugin ( reverse @$plugins ) {
2205
2206             unless ( $plugin =~ s/\A\+// ) {
2207                 $plugin = "Catalyst::Plugin::$plugin";
2208             }
2209
2210             $class->_register_plugin($plugin);
2211         }
2212     }
2213 }
2214
2215 =head2 $c->stack
2216
2217 Returns an arrayref of the internal execution stack (actions that are
2218 currently executing).
2219
2220 =head2 $c->stats_class
2221
2222 Returns or sets the stats (timing statistics) class.
2223
2224 =head2 $c->use_stats
2225
2226 Returns 1 when stats collection is enabled.  Stats collection is enabled
2227 when the -Stats options is set, debug is on or when the <MYAPP>_STATS
2228 environment variable is set.
2229
2230 Note that this is a static method, not an accessor and should be overloaded
2231 by declaring "sub use_stats { 1 }" in your MyApp.pm, not by calling $c->use_stats(1).
2232
2233 =cut
2234
2235 sub use_stats { 0 }
2236
2237
2238 =head2 $c->write( $data )
2239
2240 Writes $data to the output stream. When using this method directly, you
2241 will need to manually set the C<Content-Length> header to the length of
2242 your output data, if known.
2243
2244 =cut
2245
2246 sub write {
2247     my $c = shift;
2248
2249     # Finalize headers if someone manually writes output
2250     $c->finalize_headers;
2251
2252     return $c->engine->write( $c, @_ );
2253 }
2254
2255 =head2 version
2256
2257 Returns the Catalyst version number. Mostly useful for "powered by"
2258 messages in template systems.
2259
2260 =cut
2261
2262 sub version { return $Catalyst::VERSION }
2263
2264 =head1 INTERNAL ACTIONS
2265
2266 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
2267 C<_ACTION>, and C<_END>. These are by default not shown in the private
2268 action table, but you can make them visible with a config parameter.
2269
2270     MyApp->config->{show_internal_actions} = 1;
2271
2272 =head1 CASE SENSITIVITY
2273
2274 By default Catalyst is not case sensitive, so C<MyApp::C::FOO::Bar> is
2275 mapped to C</foo/bar>. You can activate case sensitivity with a config
2276 parameter.
2277
2278     MyApp->config->{case_sensitive} = 1;
2279
2280 This causes C<MyApp::C::Foo::Bar> to map to C</Foo/Bar>.
2281
2282 =head1 ON-DEMAND PARSER
2283
2284 The request body is usually parsed at the beginning of a request,
2285 but if you want to handle input yourself, you can enable on-demand
2286 parsing with a config parameter.
2287
2288     MyApp->config->{parse_on_demand} = 1;
2289     
2290 =head1 PROXY SUPPORT
2291
2292 Many production servers operate using the common double-server approach,
2293 with a lightweight frontend web server passing requests to a larger
2294 backend server. An application running on the backend server must deal
2295 with two problems: the remote user always appears to be C<127.0.0.1> and
2296 the server's hostname will appear to be C<localhost> regardless of the
2297 virtual host that the user connected through.
2298
2299 Catalyst will automatically detect this situation when you are running
2300 the frontend and backend servers on the same machine. The following
2301 changes are made to the request.
2302
2303     $c->req->address is set to the user's real IP address, as read from 
2304     the HTTP X-Forwarded-For header.
2305     
2306     The host value for $c->req->base and $c->req->uri is set to the real
2307     host, as read from the HTTP X-Forwarded-Host header.
2308
2309 Obviously, your web server must support these headers for this to work.
2310
2311 In a more complex server farm environment where you may have your
2312 frontend proxy server(s) on different machines, you will need to set a
2313 configuration option to tell Catalyst to read the proxied data from the
2314 headers.
2315
2316     MyApp->config->{using_frontend_proxy} = 1;
2317     
2318 If you do not wish to use the proxy support at all, you may set:
2319
2320     MyApp->config->{ignore_frontend_proxy} = 1;
2321
2322 =head1 THREAD SAFETY
2323
2324 Catalyst has been tested under Apache 2's threading C<mpm_worker>,
2325 C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
2326 believe the Catalyst core to be thread-safe.
2327
2328 If you plan to operate in a threaded environment, remember that all other
2329 modules you are using must also be thread-safe. Some modules, most notably
2330 L<DBD::SQLite>, are not thread-safe.
2331
2332 =head1 SUPPORT
2333
2334 IRC:
2335
2336     Join #catalyst on irc.perl.org.
2337
2338 Mailing Lists:
2339
2340     http://lists.rawmode.org/mailman/listinfo/catalyst
2341     http://lists.rawmode.org/mailman/listinfo/catalyst-dev
2342
2343 Web:
2344
2345     http://catalyst.perl.org
2346
2347 Wiki:
2348
2349     http://dev.catalyst.perl.org
2350
2351 =head1 SEE ALSO
2352
2353 =head2 L<Task::Catalyst> - All you need to start with Catalyst
2354
2355 =head2 L<Catalyst::Manual> - The Catalyst Manual
2356
2357 =head2 L<Catalyst::Component>, L<Catalyst::Base> - Base classes for components
2358
2359 =head2 L<Catalyst::Engine> - Core engine
2360
2361 =head2 L<Catalyst::Log> - Log class.
2362
2363 =head2 L<Catalyst::Request> - Request object
2364
2365 =head2 L<Catalyst::Response> - Response object
2366
2367 =head2 L<Catalyst::Test> - The test suite.
2368
2369 =head1 CREDITS
2370
2371 Andy Grundman
2372
2373 Andy Wardley
2374
2375 Andreas Marienborg
2376
2377 Andrew Bramble
2378
2379 Andrew Ford
2380
2381 Andrew Ruthven
2382
2383 Arthur Bergman
2384
2385 Autrijus Tang
2386
2387 Brian Cassidy
2388
2389 Carl Franks
2390
2391 Christian Hansen
2392
2393 Christopher Hicks
2394
2395 Dan Sully
2396
2397 Danijel Milicevic
2398
2399 David Kamholz
2400
2401 David Naughton
2402
2403 Drew Taylor
2404
2405 Gary Ashton Jones
2406
2407 Geoff Richards
2408
2409 Jesse Sheidlower
2410
2411 Jesse Vincent
2412
2413 Jody Belka
2414
2415 Johan Lindstrom
2416
2417 Juan Camacho
2418
2419 Leon Brocard
2420
2421 Marcus Ramberg
2422
2423 Matt S Trout
2424
2425 Robert Sedlacek
2426
2427 Sam Vilain
2428
2429 Sascha Kiefer
2430
2431 Sebastian Willert
2432
2433 Tatsuhiko Miyagawa
2434
2435 Ulf Edvinsson
2436
2437 Yuval Kogman
2438
2439 =head1 AUTHOR
2440
2441 Sebastian Riedel, C<sri@oook.de>
2442
2443 =head1 LICENSE
2444
2445 This library is free software, you can redistribute it and/or modify it under
2446 the same terms as Perl itself.
2447
2448 =cut
2449
2450 no Moose;
2451
2452 __PACKAGE__->meta->make_immutable;
2453
2454 1;