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