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