203f1c44a8053cb198e4062603fd82363f3748de
[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 blessed/;
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->depth >= $RECURSION) {
975         my $action = "$code";
976         $action = "/$action" unless $action =~ /\-\>/;
977         my $error = qq/Deep recursion detected calling "$action"/;
978         $c->log->error($error);
979         $c->error($error);
980         $c->state(0);
981         return $c->state;
982     }
983
984
985     if ( $c->debug ) {
986         my $action = "$code";
987         $action = "/$action" unless $action =~ /\-\>/;
988         $c->counter->{"$code"}++;
989
990         # determine if the call was the result of a forward
991         # this is done by walking up the call stack and looking for a calling
992         # sub of Catalyst::forward before the eval
993         my $callsub = q{};
994         for my $index ( 1 .. 10 ) {
995             last
996               if ( ( caller($index) )[0] eq 'Catalyst'
997                 && ( caller($index) )[3] eq '(eval)' );
998
999             if ( ( caller($index) )[3] =~ /forward$/ ) {
1000                 $callsub = ( caller($index) )[3];
1001                 $action  = "-> $action";
1002                 last;
1003             }
1004         }
1005
1006         my $node = Tree::Simple->new(
1007             {
1008                 action  => $action,
1009                 elapsed => undef,     # to be filled in later
1010             }
1011         );
1012         $node->setUID( "$code" . $c->counter->{"$code"} );
1013
1014         unless ( ( $code->name =~ /^_.*/ )
1015             && ( !$c->config->{show_internal_actions} ) )
1016         {
1017
1018             # is this a root-level call or a forwarded call?
1019             if ( $callsub =~ /forward$/ ) {
1020
1021                 # forward, locate the caller
1022                 if ( my $parent = $c->stack->[-1] ) {
1023                     my $visitor = Tree::Simple::Visitor::FindByUID->new;
1024                     $visitor->searchForUID(
1025                         "$parent" . $c->counter->{"$parent"} );
1026                     $c->{stats}->accept($visitor);
1027                     if ( my $result = $visitor->getResult ) {
1028                         $result->addChild($node);
1029                     }
1030                 }
1031                 else {
1032
1033                     # forward with no caller may come from a plugin
1034                     $c->{stats}->addChild($node);
1035                 }
1036             }
1037             else {
1038
1039                 # root-level call
1040                 $c->{stats}->addChild($node);
1041             }
1042         }
1043     }
1044
1045     push( @{ $c->stack }, $code );
1046     my $elapsed = 0;
1047     my $start   = 0;
1048     $start = [gettimeofday] if $c->debug;
1049     eval { $c->state( &$code( $class, $c, @{ $c->req->args } ) || 0 ) };
1050     $elapsed = tv_interval($start) if $c->debug;
1051
1052     if ( $c->debug ) {
1053         unless ( ( $code->name =~ /^_.*/ )
1054             && ( !$c->config->{show_internal_actions} ) )
1055         {
1056
1057             # FindByUID uses an internal die, so we save the existing error
1058             my $error = $@;
1059
1060             # locate the node in the tree and update the elapsed time
1061             my $visitor = Tree::Simple::Visitor::FindByUID->new;
1062             $visitor->searchForUID( "$code" . $c->counter->{"$code"} );
1063             $c->{stats}->accept($visitor);
1064             if ( my $result = $visitor->getResult ) {
1065                 my $value = $result->getNodeValue;
1066                 $value->{elapsed} = sprintf( '%fs', $elapsed );
1067                 $result->setNodeValue($value);
1068             }
1069
1070             # restore error
1071             $@ = $error || undef;
1072         }
1073     }
1074     my $last = ${ $c->stack }[-1];
1075     pop( @{ $c->stack } );
1076
1077     if ( my $error = $@ ) {
1078         if ( $error eq $DETACH ) { die $DETACH if $c->depth > 1 }
1079         else {
1080             unless ( ref $error ) {
1081                 chomp $error;
1082                 my $class = $last->class;
1083                 my $name  = $last->name;
1084                 $error = qq/Caught exception in $class->$name "$error"/;
1085             }
1086             $c->error($error);
1087             $c->state(0);
1088         }
1089     }
1090     return $c->state;
1091 }
1092
1093 =head2 $c->finalize
1094
1095 Finalizes the request.
1096
1097 =cut
1098
1099 sub finalize {
1100     my $c = shift;
1101
1102     for my $error ( @{ $c->error } ) {
1103         $c->log->error($error);
1104     }
1105
1106     $c->finalize_uploads;
1107
1108     # Error
1109     if ( $#{ $c->error } >= 0 ) {
1110         $c->finalize_error;
1111     }
1112
1113     $c->finalize_headers;
1114
1115     # HEAD request
1116     if ( $c->request->method eq 'HEAD' ) {
1117         $c->response->body('');
1118     }
1119
1120     $c->finalize_body;
1121
1122     return $c->response->status;
1123 }
1124
1125 =head2 $c->finalize_body
1126
1127 Finalizes body.
1128
1129 =cut
1130
1131 sub finalize_body { my $c = shift; $c->engine->finalize_body( $c, @_ ) }
1132
1133 =head2 $c->finalize_cookies
1134
1135 Finalizes cookies.
1136
1137 =cut
1138
1139 sub finalize_cookies { my $c = shift; $c->engine->finalize_cookies( $c, @_ ) }
1140
1141 =head2 $c->finalize_error
1142
1143 Finalizes error.
1144
1145 =cut
1146
1147 sub finalize_error { my $c = shift; $c->engine->finalize_error( $c, @_ ) }
1148
1149 =head2 $c->finalize_headers
1150
1151 Finalizes headers.
1152
1153 =cut
1154
1155 sub finalize_headers {
1156     my $c = shift;
1157
1158     # Check if we already finalized headers
1159     return if $c->response->{_finalized_headers};
1160
1161     # Handle redirects
1162     if ( my $location = $c->response->redirect ) {
1163         $c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
1164         $c->response->header( Location => $location );
1165     }
1166
1167     # Content-Length
1168     if ( $c->response->body && !$c->response->content_length ) {
1169
1170         # get the length from a filehandle
1171         if ( blessed($c->response->body) && $c->response->body->can('read') ) {
1172             if ( my $stat = stat $c->response->body ) {
1173                 $c->response->content_length( $stat->size );
1174             }
1175             else {
1176                 $c->log->warn('Serving filehandle without a content-length');
1177             }
1178         }
1179         else {
1180             $c->response->content_length( bytes::length( $c->response->body ) );
1181         }
1182     }
1183
1184     # Errors
1185     if ( $c->response->status =~ /^(1\d\d|[23]04)$/ ) {
1186         $c->response->headers->remove_header("Content-Length");
1187         $c->response->body('');
1188     }
1189
1190     $c->finalize_cookies;
1191
1192     $c->engine->finalize_headers( $c, @_ );
1193
1194     # Done
1195     $c->response->{_finalized_headers} = 1;
1196 }
1197
1198 =head2 $c->finalize_output
1199
1200 An alias for finalize_body.
1201
1202 =head2 $c->finalize_read
1203
1204 Finalizes the input after reading is complete.
1205
1206 =cut
1207
1208 sub finalize_read { my $c = shift; $c->engine->finalize_read( $c, @_ ) }
1209
1210 =head2 $c->finalize_uploads
1211
1212 Finalizes uploads. Cleans up any temporary files.
1213
1214 =cut
1215
1216 sub finalize_uploads { my $c = shift; $c->engine->finalize_uploads( $c, @_ ) }
1217
1218 =head2 $c->get_action( $action, $namespace )
1219
1220 Gets an action in a given namespace.
1221
1222 =cut
1223
1224 sub get_action { my $c = shift; $c->dispatcher->get_action(@_) }
1225
1226 =head2 $c->get_actions( $action, $namespace )
1227
1228 Gets all actions of a given name in a namespace and all parent
1229 namespaces.
1230
1231 =cut
1232
1233 sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) }
1234
1235 =head2 handle_request( $class, @arguments )
1236
1237 Called to handle each HTTP request.
1238
1239 =cut
1240
1241 sub handle_request {
1242     my ( $class, @arguments ) = @_;
1243
1244     # Always expect worst case!
1245     my $status = -1;
1246     eval {
1247         my $stats = ( $class->debug ) ? Tree::Simple->new: q{};
1248
1249         my $handler = sub {
1250             my $c = $class->prepare(@arguments);
1251             $c->{stats} = $stats;
1252             $c->dispatch;
1253             return $c->finalize;
1254         };
1255
1256         if ( $class->debug ) {
1257             my $start = [gettimeofday];
1258             $status = &$handler;
1259             my $elapsed = tv_interval $start;
1260             $elapsed = sprintf '%f', $elapsed;
1261             my $av = sprintf '%.3f',
1262               ( $elapsed == 0 ? '??' : ( 1 / $elapsed ) );
1263             my $t = Text::SimpleTable->new( [ 64, 'Action' ], [ 9, 'Time' ] );
1264
1265             $stats->traverse(
1266                 sub {
1267                     my $action = shift;
1268                     my $stat   = $action->getNodeValue;
1269                     $t->row( ( q{ } x $action->getDepth ) . $stat->{action},
1270                         $stat->{elapsed} || '??' );
1271                 }
1272             );
1273
1274             $class->log->info(
1275                 "Request took ${elapsed}s ($av/s)\n" . $t->draw );
1276         }
1277         else { $status = &$handler }
1278
1279     };
1280
1281     if ( my $error = $@ ) {
1282         chomp $error;
1283         $class->log->error(qq/Caught exception in engine "$error"/);
1284     }
1285
1286     $COUNT++;
1287     $class->log->_flush() if $class->log->can('_flush');
1288     return $status;
1289 }
1290
1291 =head2 $c->prepare( @arguments )
1292
1293 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1294 etc.).
1295
1296 =cut
1297
1298 sub prepare {
1299     my ( $class, @arguments ) = @_;
1300
1301     $class->context_class( ref $class || $class ) unless $class->context_class;
1302     my $c = $class->context_class->new(
1303         {
1304             counter => {},
1305             stack   => [],
1306             request => $class->request_class->new(
1307                 {
1308                     arguments        => [],
1309                     body_parameters  => {},
1310                     cookies          => {},
1311                     headers          => HTTP::Headers->new,
1312                     parameters       => {},
1313                     query_parameters => {},
1314                     secure           => 0,
1315                     snippets         => [],
1316                     uploads          => {}
1317                 }
1318             ),
1319             response => $class->response_class->new(
1320                 {
1321                     body    => '',
1322                     cookies => {},
1323                     headers => HTTP::Headers->new(),
1324                     status  => 200
1325                 }
1326             ),
1327             stash => {},
1328             state => 0
1329         }
1330     );
1331
1332     # For on-demand data
1333     $c->request->{_context}  = $c;
1334     $c->response->{_context} = $c;
1335     weaken( $c->request->{_context} );
1336     weaken( $c->response->{_context} );
1337
1338     if ( $c->debug ) {
1339         my $secs = time - $START || 1;
1340         my $av = sprintf '%.3f', $COUNT / $secs;
1341         $c->log->debug('**********************************');
1342         $c->log->debug("* Request $COUNT ($av/s) [$$]");
1343         $c->log->debug('**********************************');
1344         $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
1345     }
1346
1347     $c->prepare_request(@arguments);
1348     $c->prepare_connection;
1349     $c->prepare_query_parameters;
1350     $c->prepare_headers;
1351     $c->prepare_cookies;
1352     $c->prepare_path;
1353
1354     # On-demand parsing
1355     $c->prepare_body unless $c->config->{parse_on_demand};
1356
1357     my $method  = $c->req->method  || '';
1358     my $path    = $c->req->path    || '';
1359     my $address = $c->req->address || '';
1360
1361     $c->log->debug(qq/"$method" request for "$path" from "$address"/)
1362       if $c->debug;
1363
1364     $c->prepare_action;
1365
1366     return $c;
1367 }
1368
1369 =head2 $c->prepare_action
1370
1371 Prepares action.
1372
1373 =cut
1374
1375 sub prepare_action { my $c = shift; $c->dispatcher->prepare_action( $c, @_ ) }
1376
1377 =head2 $c->prepare_body
1378
1379 Prepares message body.
1380
1381 =cut
1382
1383 sub prepare_body {
1384     my $c = shift;
1385
1386     # Do we run for the first time?
1387     return if defined $c->request->{_body};
1388
1389     # Initialize on-demand data
1390     $c->engine->prepare_body( $c, @_ );
1391     $c->prepare_parameters;
1392     $c->prepare_uploads;
1393
1394     if ( $c->debug && keys %{ $c->req->body_parameters } ) {
1395         my $t = Text::SimpleTable->new( [ 37, 'Key' ], [ 36, 'Value' ] );
1396         for my $key ( sort keys %{ $c->req->body_parameters } ) {
1397             my $param = $c->req->body_parameters->{$key};
1398             my $value = defined($param) ? $param : '';
1399             $t->row( $key,
1400                 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1401         }
1402         $c->log->debug( "Body Parameters are:\n" . $t->draw );
1403     }
1404 }
1405
1406 =head2 $c->prepare_body_chunk( $chunk )
1407
1408 Prepares a chunk of data before sending it to L<HTTP::Body>.
1409
1410 =cut
1411
1412 sub prepare_body_chunk {
1413     my $c = shift;
1414     $c->engine->prepare_body_chunk( $c, @_ );
1415 }
1416
1417 =head2 $c->prepare_body_parameters
1418
1419 Prepares body parameters.
1420
1421 =cut
1422
1423 sub prepare_body_parameters {
1424     my $c = shift;
1425     $c->engine->prepare_body_parameters( $c, @_ );
1426 }
1427
1428 =head2 $c->prepare_connection
1429
1430 Prepares connection.
1431
1432 =cut
1433
1434 sub prepare_connection {
1435     my $c = shift;
1436     $c->engine->prepare_connection( $c, @_ );
1437 }
1438
1439 =head2 $c->prepare_cookies
1440
1441 Prepares cookies.
1442
1443 =cut
1444
1445 sub prepare_cookies { my $c = shift; $c->engine->prepare_cookies( $c, @_ ) }
1446
1447 =head2 $c->prepare_headers
1448
1449 Prepares headers.
1450
1451 =cut
1452
1453 sub prepare_headers { my $c = shift; $c->engine->prepare_headers( $c, @_ ) }
1454
1455 =head2 $c->prepare_parameters
1456
1457 Prepares parameters.
1458
1459 =cut
1460
1461 sub prepare_parameters {
1462     my $c = shift;
1463     $c->prepare_body_parameters;
1464     $c->engine->prepare_parameters( $c, @_ );
1465 }
1466
1467 =head2 $c->prepare_path
1468
1469 Prepares path and base.
1470
1471 =cut
1472
1473 sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) }
1474
1475 =head2 $c->prepare_query_parameters
1476
1477 Prepares query parameters.
1478
1479 =cut
1480
1481 sub prepare_query_parameters {
1482     my $c = shift;
1483
1484     $c->engine->prepare_query_parameters( $c, @_ );
1485
1486     if ( $c->debug && keys %{ $c->request->query_parameters } ) {
1487         my $t = Text::SimpleTable->new( [ 37, 'Key' ], [ 36, 'Value' ] );
1488         for my $key ( sort keys %{ $c->req->query_parameters } ) {
1489             my $param = $c->req->query_parameters->{$key};
1490             my $value = defined($param) ? $param : '';
1491             $t->row( $key,
1492                 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1493         }
1494         $c->log->debug( "Query Parameters are:\n" . $t->draw );
1495     }
1496 }
1497
1498 =head2 $c->prepare_read
1499
1500 Prepares the input for reading.
1501
1502 =cut
1503
1504 sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
1505
1506 =head2 $c->prepare_request
1507
1508 Prepares the engine request.
1509
1510 =cut
1511
1512 sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
1513
1514 =head2 $c->prepare_uploads
1515
1516 Prepares uploads.
1517
1518 =cut
1519
1520 sub prepare_uploads {
1521     my $c = shift;
1522
1523     $c->engine->prepare_uploads( $c, @_ );
1524
1525     if ( $c->debug && keys %{ $c->request->uploads } ) {
1526         my $t = Text::SimpleTable->new(
1527             [ 12, 'Key' ],
1528             [ 28, 'Filename' ],
1529             [ 18, 'Type' ],
1530             [ 9,  'Size' ]
1531         );
1532         for my $key ( sort keys %{ $c->request->uploads } ) {
1533             my $upload = $c->request->uploads->{$key};
1534             for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
1535                 $t->row( $key, $u->filename, $u->type, $u->size );
1536             }
1537         }
1538         $c->log->debug( "File Uploads are:\n" . $t->draw );
1539     }
1540 }
1541
1542 =head2 $c->prepare_write
1543
1544 Prepares the output for writing.
1545
1546 =cut
1547
1548 sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
1549
1550 =head2 $c->request_class
1551
1552 Returns or sets the request class.
1553
1554 =head2 $c->response_class
1555
1556 Returns or sets the response class.
1557
1558 =head2 $c->read( [$maxlength] )
1559
1560 Reads a chunk of data from the request body. This method is designed to
1561 be used in a while loop, reading C<$maxlength> bytes on every call.
1562 C<$maxlength> defaults to the size of the request if not specified.
1563
1564 You have to set C<MyApp-E<gt>config-E<gt>{parse_on_demand}> to use this
1565 directly.
1566
1567 =cut
1568
1569 sub read { my $c = shift; return $c->engine->read( $c, @_ ) }
1570
1571 =head2 $c->run
1572
1573 Starts the engine.
1574
1575 =cut
1576
1577 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
1578
1579 =head2 $c->set_action( $action, $code, $namespace, $attrs )
1580
1581 Sets an action in a given namespace.
1582
1583 =cut
1584
1585 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
1586
1587 =head2 $c->setup_actions($component)
1588
1589 Sets up actions for a component.
1590
1591 =cut
1592
1593 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
1594
1595 =head2 $c->setup_components
1596
1597 Sets up components.
1598
1599 =cut
1600
1601 sub setup_components {
1602     my $class = shift;
1603
1604     my $callback = sub {
1605         my ( $component, $context ) = @_;
1606
1607         unless ( $component->can('COMPONENT') ) {
1608             return $component;
1609         }
1610
1611         my $suffix = Catalyst::Utils::class2classsuffix($component);
1612         my $config = $class->config->{$suffix} || {};
1613
1614         my $instance;
1615
1616         eval { $instance = $component->COMPONENT( $context, $config ); };
1617
1618         if ( my $error = $@ ) {
1619
1620             chomp $error;
1621
1622             Catalyst::Exception->throw( message =>
1623                   qq/Couldn't instantiate component "$component", "$error"/ );
1624         }
1625
1626         Catalyst::Exception->throw( message =>
1627 qq/Couldn't instantiate component "$component", "COMPONENT() didn't return a object"/
1628           )
1629           unless ref $instance;
1630         return $instance;
1631     };
1632
1633     eval "package $class;\n" . q!Module::Pluggable::Fast->import(
1634             name   => '_catalyst_components',
1635             search => [
1636                 "$class\::Controller", "$class\::C",
1637                 "$class\::Model",      "$class\::M",
1638                 "$class\::View",       "$class\::V"
1639             ],
1640             callback => $callback
1641         );
1642     !;
1643
1644     if ( my $error = $@ ) {
1645
1646         chomp $error;
1647
1648         Catalyst::Exception->throw(
1649             message => qq/Couldn't load components "$error"/ );
1650     }
1651
1652     for my $component ( $class->_catalyst_components($class) ) {
1653         $class->components->{ ref $component || $component } = $component;
1654     }
1655 }
1656
1657 =head2 $c->setup_dispatcher
1658
1659 Sets up dispatcher.
1660
1661 =cut
1662
1663 sub setup_dispatcher {
1664     my ( $class, $dispatcher ) = @_;
1665
1666     if ($dispatcher) {
1667         $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
1668     }
1669
1670     if ( $ENV{CATALYST_DISPATCHER} ) {
1671         $dispatcher = 'Catalyst::Dispatcher::' . $ENV{CATALYST_DISPATCHER};
1672     }
1673
1674     if ( $ENV{ uc($class) . '_DISPATCHER' } ) {
1675         $dispatcher =
1676           'Catalyst::Dispatcher::' . $ENV{ uc($class) . '_DISPATCHER' };
1677     }
1678
1679     unless ($dispatcher) {
1680         $dispatcher = $class->dispatcher_class;
1681     }
1682
1683     $dispatcher->require;
1684
1685     if ($@) {
1686         Catalyst::Exception->throw(
1687             message => qq/Couldn't load dispatcher "$dispatcher", "$@"/ );
1688     }
1689
1690     # dispatcher instance
1691     $class->dispatcher( $dispatcher->new );
1692 }
1693
1694 =head2 $c->setup_engine
1695
1696 Sets up engine.
1697
1698 =cut
1699
1700 sub setup_engine {
1701     my ( $class, $engine ) = @_;
1702
1703     if ($engine) {
1704         $engine = 'Catalyst::Engine::' . $engine;
1705     }
1706
1707     if ( $ENV{CATALYST_ENGINE} ) {
1708         $engine = 'Catalyst::Engine::' . $ENV{CATALYST_ENGINE};
1709     }
1710
1711     if ( $ENV{ uc($class) . '_ENGINE' } ) {
1712         $engine = 'Catalyst::Engine::' . $ENV{ uc($class) . '_ENGINE' };
1713     }
1714
1715     if ( $ENV{MOD_PERL} ) {
1716
1717         # create the apache method
1718         {
1719             no strict 'refs';
1720             *{"$class\::apache"} = sub { shift->engine->apache };
1721         }
1722
1723         my ( $software, $version ) =
1724           $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
1725
1726         $version =~ s/_//g;
1727         $version =~ s/(\.[^.]+)\./$1/g;
1728
1729         if ( $software eq 'mod_perl' ) {
1730
1731             if ( !$engine ) {
1732
1733                 if ( $version >= 1.99922 ) {
1734                     $engine = 'Catalyst::Engine::Apache2::MP20';
1735                 }
1736
1737                 elsif ( $version >= 1.9901 ) {
1738                     $engine = 'Catalyst::Engine::Apache2::MP19';
1739                 }
1740
1741                 elsif ( $version >= 1.24 ) {
1742                     $engine = 'Catalyst::Engine::Apache::MP13';
1743                 }
1744
1745                 else {
1746                     Catalyst::Exception->throw( message =>
1747                           qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
1748                 }
1749
1750             }
1751
1752             # install the correct mod_perl handler
1753             if ( $version >= 1.9901 ) {
1754                 *handler = sub  : method {
1755                     shift->handle_request(@_);
1756                 };
1757             }
1758             else {
1759                 *handler = sub ($$) { shift->handle_request(@_) };
1760             }
1761
1762         }
1763
1764         elsif ( $software eq 'Zeus-Perl' ) {
1765             $engine = 'Catalyst::Engine::Zeus';
1766         }
1767
1768         else {
1769             Catalyst::Exception->throw(
1770                 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
1771         }
1772     }
1773
1774     unless ($engine) {
1775         $engine = $class->engine_class;
1776     }
1777
1778     $engine->require;
1779
1780     if ($@) {
1781         Catalyst::Exception->throw( message =>
1782 qq/Couldn't load engine "$engine" (maybe you forgot to install it?), "$@"/
1783         );
1784     }
1785
1786     # check for old engines that are no longer compatible
1787     my $old_engine;
1788     if ( $engine->isa('Catalyst::Engine::Apache')
1789         && !Catalyst::Engine::Apache->VERSION )
1790     {
1791         $old_engine = 1;
1792     }
1793
1794     elsif ( $engine->isa('Catalyst::Engine::Server::Base')
1795         && Catalyst::Engine::Server->VERSION le '0.02' )
1796     {
1797         $old_engine = 1;
1798     }
1799
1800     elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
1801         && $engine->VERSION eq '0.01' )
1802     {
1803         $old_engine = 1;
1804     }
1805
1806     elsif ($engine->isa('Catalyst::Engine::Zeus')
1807         && $engine->VERSION eq '0.01' )
1808     {
1809         $old_engine = 1;
1810     }
1811
1812     if ($old_engine) {
1813         Catalyst::Exception->throw( message =>
1814               qq/Engine "$engine" is not supported by this version of Catalyst/
1815         );
1816     }
1817
1818     # engine instance
1819     $class->engine( $engine->new );
1820 }
1821
1822 =head2 $c->setup_home
1823
1824 Sets up the home directory.
1825
1826 =cut
1827
1828 sub setup_home {
1829     my ( $class, $home ) = @_;
1830
1831     if ( $ENV{CATALYST_HOME} ) {
1832         $home = $ENV{CATALYST_HOME};
1833     }
1834
1835     if ( $ENV{ uc($class) . '_HOME' } ) {
1836         $home = $ENV{ uc($class) . '_HOME' };
1837     }
1838
1839     unless ($home) {
1840         $home = Catalyst::Utils::home($class);
1841     }
1842
1843     if ($home) {
1844         $class->config->{home} ||= $home;
1845         $class->config->{root} ||= dir($home)->subdir('root');
1846     }
1847 }
1848
1849 =head2 $c->setup_log
1850
1851 Sets up log.
1852
1853 =cut
1854
1855 sub setup_log {
1856     my ( $class, $debug ) = @_;
1857
1858     unless ( $class->log ) {
1859         $class->log( Catalyst::Log->new );
1860     }
1861
1862     my $app_flag = Catalyst::Utils::class2env($class) . '_DEBUG';
1863
1864     if (
1865           ( defined( $ENV{CATALYST_DEBUG} ) || defined( $ENV{$app_flag} ) )
1866         ? ( $ENV{CATALYST_DEBUG} || $ENV{$app_flag} )
1867         : $debug
1868       )
1869     {
1870         no strict 'refs';
1871         *{"$class\::debug"} = sub { 1 };
1872         $class->log->debug('Debug messages enabled');
1873     }
1874 }
1875
1876 =head2 $c->setup_plugins
1877
1878 Sets up plugins.
1879
1880 =cut
1881
1882 =head2 $c->registered_plugins 
1883
1884 Returns a sorted list of the plugins which have either been stated in the
1885 import list or which have been added via C<< MyApp->plugin(@args); >>.
1886
1887 If passed a given plugin name, it will report a boolean value indicating
1888 whether or not that plugin is loaded.  A fully qualified name is required if
1889 the plugin name does not begin with C<Catalyst::Plugin::>.
1890
1891  if ($c->registered_plugins('Some::Plugin')) {
1892      ...
1893  }
1894
1895 =cut
1896
1897 {
1898
1899     sub registered_plugins {
1900         my $proto = shift;
1901         return sort keys %{$proto->_plugins} unless @_;
1902         my $plugin = shift;
1903         return 1 if exists $proto->_plugins->{$plugin};
1904         return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
1905     }
1906
1907     sub _register_plugin {
1908         my ( $proto, $plugin, $instant ) = @_;
1909         my $class = ref $proto || $proto;
1910
1911         $plugin->require;
1912
1913         if ( my $error = $@ ) {
1914             my $type = $instant ? "instant " : '';
1915             Catalyst::Exception->throw(
1916                 message => qq/Couldn't load ${type}plugin "$plugin", $error/ );
1917         }
1918
1919         $proto->_plugins->{$plugin} = 1;        
1920         unless ($instant) {
1921             no strict 'refs';
1922             unshift @{"$class\::ISA"}, $plugin;
1923         }
1924         return $class;
1925     }
1926
1927     sub setup_plugins {
1928         my ( $class, $plugins ) = @_;
1929
1930         $class->_plugins( {} ) unless $class->_plugins;
1931         $plugins ||= [];
1932         for my $plugin ( reverse @$plugins ) {
1933
1934             unless ( $plugin =~ s/\A\+// ) {
1935                 $plugin = "Catalyst::Plugin::$plugin";
1936             }
1937
1938             $class->_register_plugin($plugin);
1939         }
1940     }
1941 }
1942
1943 =head2 $c->stack
1944
1945 Returns the stack.
1946
1947 =head2 $c->write( $data )
1948
1949 Writes $data to the output stream. When using this method directly, you
1950 will need to manually set the C<Content-Length> header to the length of
1951 your output data, if known.
1952
1953 =cut
1954
1955 sub write {
1956     my $c = shift;
1957
1958     # Finalize headers if someone manually writes output
1959     $c->finalize_headers;
1960
1961     return $c->engine->write( $c, @_ );
1962 }
1963
1964 =head2 version
1965
1966 Returns the Catalyst version number. Mostly useful for "powered by"
1967 messages in template systems.
1968
1969 =cut
1970
1971 sub version { return $Catalyst::VERSION }
1972
1973 =head1 INTERNAL ACTIONS
1974
1975 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
1976 C<_ACTION>, and C<_END>. These are by default not shown in the private
1977 action table, but you can make them visible with a config parameter.
1978
1979     MyApp->config->{show_internal_actions} = 1;
1980
1981 =head1 CASE SENSITIVITY
1982
1983 By default Catalyst is not case sensitive, so C<MyApp::C::FOO::Bar> is
1984 mapped to C</foo/bar>. You can activate case sensitivity with a config
1985 parameter.
1986
1987     MyApp->config->{case_sensitive} = 1;
1988
1989 This causes C<MyApp::C::Foo::Bar> to map to C</Foo/Bar>.
1990
1991 =head1 ON-DEMAND PARSER
1992
1993 The request body is usually parsed at the beginning of a request,
1994 but if you want to handle input yourself or speed things up a bit,
1995 you can enable on-demand parsing with a config parameter.
1996
1997     MyApp->config->{parse_on_demand} = 1;
1998     
1999 =head1 PROXY SUPPORT
2000
2001 Many production servers operate using the common double-server approach,
2002 with a lightweight frontend web server passing requests to a larger
2003 backend server. An application running on the backend server must deal
2004 with two problems: the remote user always appears to be C<127.0.0.1> and
2005 the server's hostname will appear to be C<localhost> regardless of the
2006 virtual host that the user connected through.
2007
2008 Catalyst will automatically detect this situation when you are running
2009 the frontend and backend servers on the same machine. The following
2010 changes are made to the request.
2011
2012     $c->req->address is set to the user's real IP address, as read from 
2013     the HTTP X-Forwarded-For header.
2014     
2015     The host value for $c->req->base and $c->req->uri is set to the real
2016     host, as read from the HTTP X-Forwarded-Host header.
2017
2018 Obviously, your web server must support these headers for this to work.
2019
2020 In a more complex server farm environment where you may have your
2021 frontend proxy server(s) on different machines, you will need to set a
2022 configuration option to tell Catalyst to read the proxied data from the
2023 headers.
2024
2025     MyApp->config->{using_frontend_proxy} = 1;
2026     
2027 If you do not wish to use the proxy support at all, you may set:
2028
2029     MyApp->config->{ignore_frontend_proxy} = 1;
2030
2031 =head1 THREAD SAFETY
2032
2033 Catalyst has been tested under Apache 2's threading mpm_worker, mpm_winnt,
2034 and the standalone forking HTTP server on Windows. We believe the Catalyst
2035 core to be thread-safe.
2036
2037 If you plan to operate in a threaded environment, remember that all other
2038 modules you are using must also be thread-safe. Some modules, most notably
2039 L<DBD::SQLite>, are not thread-safe.
2040
2041 =head1 SUPPORT
2042
2043 IRC:
2044
2045     Join #catalyst on irc.perl.org.
2046
2047 Mailing Lists:
2048
2049     http://lists.rawmode.org/mailman/listinfo/catalyst
2050     http://lists.rawmode.org/mailman/listinfo/catalyst-dev
2051
2052 Web:
2053
2054     http://catalyst.perl.org
2055
2056 Wiki:
2057
2058     http://dev.catalyst.perl.org
2059
2060 =head1 SEE ALSO
2061
2062 =head2 L<Task::Catalyst> - All you need to start with Catalyst
2063
2064 =head2 L<Catalyst::Manual> - The Catalyst Manual
2065
2066 =head2 L<Catalyst::Component>, L<Catalyst::Base> - Base classes for components
2067
2068 =head2 L<Catalyst::Engine> - Core engine
2069
2070 =head2 L<Catalyst::Log> - Log class.
2071
2072 =head2 L<Catalyst::Request> - Request object
2073
2074 =head2 L<Catalyst::Response> - Response object
2075
2076 =head2 L<Catalyst::Test> - The test suite.
2077
2078 =head1 CREDITS
2079
2080 Andy Grundman
2081
2082 Andy Wardley
2083
2084 Andreas Marienborg
2085
2086 Andrew Bramble
2087
2088 Andrew Ford
2089
2090 Andrew Ruthven
2091
2092 Arthur Bergman
2093
2094 Autrijus Tang
2095
2096 Brian Cassidy
2097
2098 Carl Franks
2099
2100 Christian Hansen
2101
2102 Christopher Hicks
2103
2104 Dan Sully
2105
2106 Danijel Milicevic
2107
2108 David Kamholz
2109
2110 David Naughton
2111
2112 Drew Taylor
2113
2114 Gary Ashton Jones
2115
2116 Geoff Richards
2117
2118 Jesse Sheidlower
2119
2120 Jesse Vincent
2121
2122 Jody Belka
2123
2124 Johan Lindstrom
2125
2126 Juan Camacho
2127
2128 Leon Brocard
2129
2130 Marcus Ramberg
2131
2132 Matt S Trout
2133
2134 Robert Sedlacek
2135
2136 Sam Vilain
2137
2138 Sascha Kiefer
2139
2140 Tatsuhiko Miyagawa
2141
2142 Ulf Edvinsson
2143
2144 Yuval Kogman
2145
2146 =head1 AUTHOR
2147
2148 Sebastian Riedel, C<sri@oook.de>
2149
2150 =head1 LICENSE
2151
2152 This library is free software, you can redistribute it and/or modify it under
2153 the same terms as Perl itself.
2154
2155 =cut
2156
2157 1;