X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FDispatcher.pm;h=35f129fef8f167028df02383cbff5b2caf0ab780;hb=7101bd1f9d86faa21526f6601dbdb401c679501c;hp=5fc33c0d1345135ffde317b01644b747e1d471ca;hpb=684d10edf63074f94667d437db01d30b8d13cefc;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst/Dispatcher.pm b/lib/Catalyst/Dispatcher.pm index 5fc33c0..35f129f 100644 --- a/lib/Catalyst/Dispatcher.pm +++ b/lib/Catalyst/Dispatcher.pm @@ -17,7 +17,7 @@ use overload '""' => sub { return ref shift }, fallback => 1; __PACKAGE__->mk_accessors( qw/tree dispatch_types registered_dispatch_types - method_action_class action_container_class/ + method_action_class action_container_class reserved_actions/ ); # Preload these action types @@ -26,6 +26,9 @@ our @PRELOAD = qw/Path Regex/; # Postload these action types our @POSTLOAD = qw/Index Default/; +# Reserved action names +our @RESERVED = qw/begin auto default index end/; + =head1 NAME Catalyst::Dispatcher - The Catalyst Dispatcher @@ -58,7 +61,7 @@ sub dispatch { my ( $self, $c ) = @_; if ( $c->action ) { - $c->forward( join( '/', '', $c->namespace, '_DISPATCH' ) ); + $c->forward( join( '/', '', $c->action->namespace, '_DISPATCH' ) ); } else { @@ -85,7 +88,12 @@ sub forward { return 0; } - my $arguments = ( ref( $_[-1] ) eq 'ARRAY' ) ? pop(@_) : $c->req->args; + my $local_args = 0; + my $arguments = $c->req->args; + if ( ref( $_[-1] ) eq 'ARRAY' ) { + $arguments = pop(@_); + $local_args = 1; + } my $result; @@ -93,7 +101,7 @@ sub forward { my $command_copy = $command; unless ( $command_copy =~ s/^\/// ) { - my $namespace = $c->namespace; + my $namespace = $c->stack->[-1]->namespace; $command_copy = "${namespace}/${command}"; } @@ -106,8 +114,9 @@ sub forward { my $tail = $2; $result = $c->get_action( $tail, $1 ); if ($result) { - $command = $tail; - push( @{$arguments}, @extra_args ); + $local_args = 1; + $command = $tail; + unshift( @{$arguments}, @extra_args ); last DESCEND; } unshift( @extra_args, $tail ); @@ -135,7 +144,9 @@ qq/Couldn't forward to command "$command". Invalid action or component./; code => $code, reverse => "$class->$method", class => $class, - namespace => $class, + namespace => Catalyst::Utils::class2prefix( + $class, $c->config->{case_sensitive} + ), } ); $result = $action; @@ -152,9 +163,11 @@ qq/Couldn't forward to command "$command". Invalid action or component./; } - local $c->request->{arguments} = [ @{$arguments} ]; - - $result->execute($c); + if ($local_args) { + local $c->request->{arguments} = [ @{$arguments} ]; + $result->execute($c); + } + else { $result->execute($c) } return $c->state; } @@ -184,10 +197,12 @@ sub prepare_action { } # If not, move the last part path to args - unshift @args, pop @path; } + $c->log->debug( 'Path is "' . $c->req->match . '"' ) + if ( $c->debug && $c->req->match ); + $c->log->debug( 'Arguments are "' . join( '/', @args ) . '"' ) if ( $c->debug && @args ); } @@ -268,9 +283,42 @@ sub get_containers { return map { $_->getNodeValue } @match; } +=item $self->register( $c, $action ) + +=cut + sub register { my ( $self, $c, $action ) = @_; + my $registered = $self->registered_dispatch_types; + + my $priv = 0; + foreach my $key ( keys %{ $action->attributes } ) { + $priv++ if $key eq 'Private'; + my $class = "Catalyst::DispatchType::$key"; + unless ( $registered->{$class} ) { + eval "require $class"; + push( @{ $self->dispatch_types }, $class->new ) unless $@; + $registered->{$class} = 1; + } + } + + # Check if action name is reserved + my $reserved = 0; + for my $name ( @{ $self->reserved_actions } ) { + $reserved++ if $action->name eq $name; + } + + # Pass the action to our dispatch types so they can register it if reqd. + my $reg = $reserved; + unless ($reserved) { + foreach my $type ( @{ $self->dispatch_types } ) { + $reg++ if $type->register( $c, $action ); + } + } + + return unless $reg + $priv; + my $namespace = $action->namespace; my $parent = $self->tree; my $visitor = Tree::Simple::Visitor::FindByPath->new; @@ -301,22 +349,6 @@ sub register { # Set the method value $parent->getNodeValue->actions->{ $action->name } = $action; - - my $registered = $self->registered_dispatch_types; - - foreach my $key ( keys %{ $action->attributes } ) { - my $class = "Catalyst::DispatchType::$key"; - unless ( $registered->{$class} ) { - eval "require $class"; - push( @{ $self->dispatch_types }, $class->new ) unless $@; - $registered->{$class} = 1; - } - } - - # Pass the action to our dispatch types so they can register it if reqd. - foreach my $type ( @{ $self->dispatch_types } ) { - $type->register( $c, $action ); - } } =item $self->setup_actions( $class, $component ) @@ -328,6 +360,7 @@ sub setup_actions { $self->dispatch_types( [] ); $self->registered_dispatch_types( {} ); + $self->reserved_actions( \@RESERVED ); $self->method_action_class('Catalyst::Action'); $self->action_container_class('Catalyst::ActionContainer'); @@ -362,9 +395,9 @@ sub setup_actions { return unless $c->debug; my $privates = Text::SimpleTable->new( - [ 24, 'Private' ], - [ 23, 'Class' ], - [ 23, 'Method' ] + [ 20, 'Private' ], + [ 38, 'Class' ], + [ 12, 'Method' ] ); my $has_private = 0;