better debug info
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Engine.pm
index 98a1f92..21e0da2 100644 (file)
@@ -127,7 +127,9 @@ sub finalize {
     if ( my $location = $c->res->redirect ) {
         $c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
         $c->res->headers->header( Location => $location );
+        $c->res->headers->remove_content_headers;
         $c->res->status(302);
+        return $c->finalize_headers;
     }
 
     if ( !$c->res->output || $#{ $c->error } >= 0 ) {
@@ -250,7 +252,7 @@ sub finalize_output { }
 Forward processing to a private action or a method from a class.
 If you define a class without method it will default to process().
 
-    $c->forward('foo');
+    $c->forward('/foo');
     $c->forward('index');
     $c->forward(qw/MyApp::Model::CDBI::Foo do_stuff/);
     $c->forward('MyApp::View::TT');
@@ -266,7 +268,7 @@ sub forward {
     }
     my $caller    = caller(0);
     my $namespace = '/';
-    if ( $command =~ /^\/$/ ) {
+    if ( $command =~ /^\// ) {
         $command =~ /^(.*)\/(\w+)$/;
         $namespace = $1 || '/';
         $command = $2;
@@ -373,11 +375,13 @@ sub handler ($$) {
                 for my $begin ( @{ $c->get_action( 'begin', $namespace ) } ) {
                     $c->state( $c->execute( @{ $begin->[0] } ) );
                 }
-                for my $result ( @{ $c->get_action( $action, $default ) } ) {
+                for my $result ( @{ $c->get_action( $action, $default ) }[-1] )
+                {
                     $c->state( $c->execute( @{ $result->[0] } ) );
                     last unless $default;
                 }
-                for my $end ( @{ $c->get_action( 'end', $namespace ) } ) {
+                for my $end ( reverse @{ $c->get_action( 'end', $namespace ) } )
+                {
                     $c->state( $c->execute( @{ $end->[0] } ) );
                 }
             }
@@ -444,8 +448,8 @@ sub prepare {
     }
     $c->prepare_request($r);
     $c->prepare_path;
-    $c->prepare_cookies;
     $c->prepare_headers;
+    $c->prepare_cookies;
     $c->prepare_connection;
     my $method   = $c->req->method   || '';
     my $path     = $c->req->path     || '';
@@ -462,7 +466,7 @@ sub prepare {
             my $value = $c->req->params->{$key} || '';
             push @params, "$key=$value";
         }
-        $c->log->debug( 'Parameters are "' . join( ' ', @params ) . '"' );
+        $c->log->debug( 'Parameters are', @params );
     }
     $c->prepare_uploads;
     return $c;
@@ -638,11 +642,11 @@ sub set_action {
     my %flags;
 
     for my $attr ( @{$attrs} ) {
-        if    ( $attr =~ /^Local$/ )         { $flags{local}++ }
-        elsif ( $attr =~ /^Global$/ )        { $flags{global}++ }
-        elsif ( $attr =~ /^Path\((.+)\)$/i ) { $flags{path} = $1 }
-        elsif ( $attr =~ /^Private$/i )      { $flags{private}++ }
-        elsif ( $attr =~ /Regex\((.+)\)$/i ) { $flags{regex} = $1 }
+        if    ( $attr =~ /^(Local|Relative)$/ )        { $flags{local}++ }
+        elsif ( $attr =~ /^(Global|Absolute)$/ )       { $flags{global}++ }
+        elsif ( $attr =~ /^Path\((.+)\)$/i )           { $flags{path} = $1 }
+        elsif ( $attr =~ /^Private$/i )                { $flags{private}++ }
+        elsif ( $attr =~ /^(Regex|Regexp)\((.+)\)$/i ) { $flags{regex} = $2 }
     }
 
     return unless keys %flags;
@@ -664,8 +668,6 @@ sub set_action {
     my $uid = $parent->getUID;
     $c->actions->{private}->{$uid}->{$method} = [ $namespace, $code ];
     my $forward = $prefix ? "$prefix/$method" : $method;
-    $c->log->debug(qq|Private "/$forward" is "$namespace->$method"|)
-      if $c->debug;
 
     if ( $flags{path} ) {
         $flags{path} =~ s/^\w+//;
@@ -689,14 +691,13 @@ sub set_action {
             $path     = $1;
             $absolute = 1;
         }
+        $absolute = 1 if $flags{global};
         my $name = $absolute ? $path : "$prefix/$path";
         $c->actions->{plain}->{$name} = [ $namespace, $code ];
-        $c->log->debug(qq|Public "/$name" is "/$forward"|) if $c->debug;
     }
     if ( my $regex = $flags{regex} ) {
         push @{ $c->actions->{compiled} }, [ $regex, qr#$regex# ];
         $c->actions->{regex}->{$regex} = [ $namespace, $code ];
-        $c->log->debug(qq|Public "$regex" is "/$forward"|) if $c->debug;
     }
 
     $c->actions->{reverse}->{"$code"} = $reverse;
@@ -732,10 +733,23 @@ sub setup_actions {
         my ( $code, $attrs ) = @{$action};
         my $name = '';
         no strict 'refs';
-        for my $sym ( values %{ $comp . '::' } ) {
-            if ( *{$sym}{CODE} && *{$sym}{CODE} == $code ) {
-                $name = *{$sym}{NAME};
-                $self->set_action( $name, $code, $comp, $attrs );
+        my @cache = ( $comp, @{"$comp\::ISA"} );
+        my %namespaces;
+        while ( my $namespace = shift @cache ) {
+            $namespaces{$namespace}++;
+            for my $isa ( @{"$comp\::ISA"} ) {
+                next if $namespaces{$isa};
+                push @cache, $isa;
+                $namespaces{$isa}++;
+            }
+        }
+        for my $namespace ( keys %namespaces ) {
+            for my $sym ( values %{ $namespace . '::' } ) {
+                if ( *{$sym}{CODE} && *{$sym}{CODE} == $code ) {
+                    $name = *{$sym}{NAME};
+                    $self->set_action( $name, $code, $comp, $attrs );
+                    last;
+                }
             }
         }
     }
@@ -773,10 +787,37 @@ sub setup_components {
         $self->components->{ ref $comp } = $comp;
         $self->setup_actions($comp);
     }
-    $self->log->debug( 'Initialized components "'
-          . join( ' ', keys %{ $self->components } )
-          . '"' )
-      if $self->debug;
+    my @comps = keys %{ $self->components };
+    $self->log->debug( 'Loaded components', @comps )
+      if ( @comps && $self->debug );
+    my $actions  = $self->actions;
+    my @messages = ('Loaded private actions');
+    my $walker   = sub {
+        my ( $walker, $parent, $messages, $prefix ) = @_;
+        $prefix .= $parent->getNodeValue || '';
+        $prefix .= '/' unless $prefix =~ /\/$/;
+        my $uid = $parent->getUID;
+        for my $action ( keys %{ $actions->{private}->{$uid} } ) {
+            my ( $class, $code ) = @{ $actions->{private}->{$uid}->{$action} };
+            push @$messages, qq/"$prefix$action" in "$class" as "$code"/;
+        }
+        $walker->( $walker, $_, $messages, $prefix )
+          for $parent->getAllChildren;
+    };
+    $walker->( $walker, $self->tree, \@messages, '' );
+    $self->log->debug(@messages) if ( $#messages && $self->debug );
+    @messages = ('Loaded plain actions');
+    for my $plain ( keys %{ $actions->{plain} } ) {
+        my ( $class, $code ) = @{ $actions->{plain}->{$plain} };
+        push @messages, qq|"/$plain" in "$class" as "$code"|;
+    }
+    $self->log->debug(@messages) if ( $#messages && $self->debug );
+    @messages = ('Loaded regex actions');
+    for my $regex ( keys %{ $actions->{regex} } ) {
+        my ( $class, $code ) = @{ $actions->{regex}->{$regex} };
+        push @messages, qq|"$regex" in "$class" as "$code"|;
+    }
+    $self->log->debug(@messages) if ( $#messages && $self->debug );
 }
 
 =item $c->stash
@@ -808,9 +849,11 @@ sub _prefix {
 
 sub _class2prefix {
     my $class = shift || '';
-    $class =~ /^.*::([MVC]|Model|View|Controller)?::(.*)$/;
-    my $prefix = lc $2 || '';
-    $prefix =~ s/\:\:/\//g;
+    my $prefix;
+    if ( $class =~ /^.*::([MVC]|Model|View|Controller)?::(.*)$/ ) {
+        $prefix = lc $2;
+        $prefix =~ s/\:\:/\//g;
+    }
     return $prefix;
 }