X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FDispatcher.pm;h=ee513e76f530803d8712c16d1a3ba1c9ff542b16;hb=79a3189aaa44faea53317e3166ccd36d7603add8;hp=0fa02b549399785018b85b7ad3c7a168e6b4df94;hpb=11bd4e3eaa29685c44318041381621e79c4a5f44;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst/Dispatcher.pm b/lib/Catalyst/Dispatcher.pm index 0fa02b5..ee513e7 100644 --- a/lib/Catalyst/Dispatcher.pm +++ b/lib/Catalyst/Dispatcher.pm @@ -55,56 +55,7 @@ sub dispatch { my ( $self, $c ) = @_; if ( $c->action ) { - - my @containers = $self->get_containers( $c->namespace ); - my %actions; - foreach my $name (qw/begin auto end/) { - - # Go down the container list representing each part of the - # current namespace inheritance tree, grabbing the actions hash - # of the ActionContainer object and looking for actions of the - # appropriate name registered to the namespace - - $actions{$name} = [ - map { $_->{$name} } - grep { exists $_->{$name} } - map { $_->actions } @containers - ]; - } - - # Errors break the normal flow and the end action is instantly run - my $error = 0; - - # Execute last begin - $c->state(1); - if ( my $begin = @{ $actions{begin} }[-1] ) { - $begin->execute($c); - $error++ if scalar @{ $c->error }; - } - - # Execute the auto chain - my $autorun = 0; - for my $auto ( @{ $actions{auto} } ) { - last if $error; - $autorun++; - $auto->execute($c); - $error++ if scalar @{ $c->error }; - last unless $c->state; - } - - # Execute the action or last default - my $mkay = $autorun ? $c->state ? 1 : 0 : 1; - if ($mkay) { - unless ($error) { - $c->action->execute($c); - $error++ if scalar @{ $c->error }; - } - } - - # Execute last end - if ( my $end = @{ $actions{end} }[-1] ) { - $end->execute($c); - } + $c->forward( join( '/', '', $c->namespace, '_DISPATCH' ) ); } else { @@ -137,7 +88,7 @@ sub forward { my $arguments = ( ref( $_[-1] ) eq 'ARRAY' ) ? pop(@_) : $c->req->args; - my $results = []; + my $result; my $command_copy = $command; @@ -149,14 +100,14 @@ sub forward { } unless ( $command_copy =~ /\// ) { - $results = $c->get_action( $command_copy, '/' ); + $result = $c->get_action( $command_copy, '/' ); } else { my @extra_args; DESCEND: while ( $command_copy =~ s/^(.*)\/(\w+)$/$1/ ) { my $tail = $2; - $results = $c->get_action( $tail, $1 ); - if ( @{$results} ) { + $result = $c->get_action( $tail, $1 ); + if ( $result ) { $command = $tail; push( @{$arguments}, @extra_args ); last DESCEND; @@ -165,7 +116,7 @@ sub forward { } } - unless ( @{$results} ) { + unless ( $result ) { unless ( $c->components->{$command} ) { my $error = @@ -188,7 +139,7 @@ qq/Couldn't forward to command "$command". Invalid action or component./; namespace => $class, } ); - $results = [ [$action] ]; + $result = $action; } else { @@ -204,11 +155,7 @@ qq/Couldn't forward to command "$command". Invalid action or component./; local $c->request->{arguments} = [ @{$arguments} ]; - for my $result ( @{$results} ) { - $result->[0]->execute($c); - return if scalar @{ $c->error }; - last unless $c->state; - } + $result->execute($c); return $c->state; } @@ -246,41 +193,41 @@ sub prepare_action { if ( $c->debug && @args ); } -=item $self->get_action( $c, $action, $namespace, $inherit ) +=item $self->get_action( $c, $action, $namespace ) =cut sub get_action { - my ( $self, $c, $action, $namespace, $inherit ) = @_; - return [] unless $action; + my ( $self, $c, $name, $namespace ) = @_; + return unless $name; $namespace ||= ''; $namespace = '' if $namespace eq '/'; - $inherit ||= 0; my @match = $self->get_containers($namespace); - if ($inherit) { # Return [ [ $act_obj ], ... ] for valid containers - return [ - map { [ $_->{$action} ] } # Make [ $action_obj ] - grep { defined $_->{$action} } # If it exists in the container - map { $_->actions } # Get action hash for container - @match - ]; - } - else { - my $node = $match[-1]->actions; # Only bother looking at the last one + return unless @match; - if ( defined $node->{$action} - && ( $node->{$action}->namespace eq $namespace ) ) - { - return [ [ $node->{$action} ] ]; - } - else { - return []; - } + if ( my $action = $match[-1]->get_action( $c, $name ) ) + { + return $action if $action->namespace eq $namespace; } } +=item $self->get_actions( $c, $action, $namespace ) + +=cut + +sub get_actions { + my ( $self, $c, $action, $namespace ) = @_; + return [] unless $action; + $namespace ||= ''; + $namespace = '' if $namespace eq '/'; + + my @match = $self->get_containers($namespace); + + return map { $_->get_action($c, $action) } @match; +} + =item $self->get_containers( $namespace ) =cut @@ -368,8 +315,28 @@ sub set_action { } return unless keys %attributes; - my $parent = $self->tree; - my $visitor = Tree::Simple::Visitor::FindByPath->new; + my $reverse = $namespace ? "$namespace/$method" : $method; + + my $action = Catalyst::Action->new( + { + name => $method, + code => $code, + reverse => $reverse, + namespace => $namespace, + class => $class, + attributes => \%attributes, + } + ); + + $self->register($c, $action); +} + +sub register { + my ( $self, $c, $action ) = @_; + + my $namespace = $action->namespace; + my $parent = $self->tree; + my $visitor = Tree::Simple::Visitor::FindByPath->new; if ($namespace) { for my $part ( split '/', $namespace ) { @@ -395,21 +362,8 @@ sub set_action { } } - my $reverse = $namespace ? "$namespace/$method" : $method; - - my $action = Catalyst::Action->new( - { - name => $method, - code => $code, - reverse => $reverse, - namespace => $namespace, - class => $class, - attributes => \%attributes, - } - ); - # Set the method value - $parent->getNodeValue->actions->{$method} = $action; + $parent->getNodeValue->actions->{$action->name} = $action; # Pass the action to our dispatch types so they can register it if reqd. foreach my $type ( @{ $self->dispatch_types } ) { @@ -454,7 +408,7 @@ sub setup_actions { while ( my $class = shift @cache ) { $classes{$class}++; - for my $isa ( @{"$comp\::ISA"} ) { + for my $isa ( @{"$class\::ISA"} ) { next if $classes{$isa}; push @cache, $isa; $classes{$isa}++; @@ -497,6 +451,9 @@ sub setup_actions { for my $action ( keys %{$node} ) { my $action_obj = $node->{$action}; + next + if ( ( $action =~ /^_.*/ ) + && ( !$c->config->{show_internal_actions} ) ); $privates->addRow( "$prefix$action", $action_obj->class ); }