X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=blobdiff_plain;f=lib%2FCatalyst%2FDispatcher.pm;h=7c5134be1463365e13358b65d4bc40e2f5804ae0;hp=78bb5a39b0a795bfea19bfa8c9ae679b65dcbda7;hb=f3414019f472b55682ef3af53f761b6db7955887;hpb=059c085bfcead450e70ace9ef193aa99ac2ab37d diff --git a/lib/Catalyst/Dispatcher.pm b/lib/Catalyst/Dispatcher.pm index 78bb5a3..7c5134b 100644 --- a/lib/Catalyst/Dispatcher.pm +++ b/lib/Catalyst/Dispatcher.pm @@ -1,6 +1,7 @@ package Catalyst::Dispatcher; use Moose; +use Class::MOP; use Catalyst::Exception; use Catalyst::Utils; @@ -13,25 +14,23 @@ use Tree::Simple; use Tree::Simple::Visitor::FindByPath; use Scalar::Util (); -# Stringify to class -use overload '""' => sub { return ref shift }, fallback => 1; - - +#do these belong as package vars or should we build these via a builder method? # Preload these action types our @PRELOAD = qw/Index Path Regex/; # Postload these action types our @POSTLOAD = qw/Default/; -has _tree => (is => 'rw'); -has _dispatch_types => (is => 'rw'); -has _registered_dispatch_types => (is => 'rw'); -has _method_action_class => (is => 'rw'); -has _action_container_class => (is => 'rw'); -has preload_dispatch_types => (is => 'rw', required => 1, lazy => 1, default => sub { [@PRELOAD] }); -has postload_dispatch_types => (is => 'rw', required => 1, lazy => 1, default => sub { [@POSTLOAD] }); -has _action_hash => (is => 'rw', required => 1, lazy => 1, default => sub { {} }); -has _container_hash => (is => 'rw', required => 1, lazy => 1, default => sub { {} }); +has _tree => (is => 'rw'); +has _dispatch_types => (is => 'rw', default => sub { [] }, required => 1, lazy => 1); +has _registered_dispatch_types => (is => 'rw', default => sub { {} }, required => 1, lazy => 1); +has _method_action_class => (is => 'rw', default => 'Catalyst::Action'); +has _action_container_class => (is => 'rw', default => 'Catalyst::ActionContainer'); + +has preload_dispatch_types => (is => 'rw', required => 1, lazy => 1, default => sub { [@PRELOAD] }); +has postload_dispatch_types => (is => 'rw', required => 1, lazy => 1, default => sub { [@POSTLOAD] }); +has _action_hash => (is => 'rw', required => 1, lazy => 1, default => sub { {} }); +has _container_hash => (is => 'rw', required => 1, lazy => 1, default => sub { {} }); no Moose; @@ -59,7 +58,7 @@ Construct a new dispatcher. sub BUILD { my ($self, $params) = @_; - my $container = + my $container = Catalyst::ActionContainer->new( { part => '/', actions => {} } ); $self->_tree( Tree::Simple->new( $container, Tree::Simple->ROOT ) ); @@ -107,8 +106,8 @@ message about unknown resource sub dispatch { my ( $self, $c ) = @_; - if ( $c->action ) { - $c->forward( join( '/', '', $c->action->namespace, '_DISPATCH' ) ); + if ( my $action = $c->action ) { + $c->forward( join( '/', '', $action->namespace, '_DISPATCH' ) ); } else { @@ -136,7 +135,7 @@ sub forward { } my @args; - + if ( ref( $extra_params[-1] ) eq 'ARRAY' ) { @args = @{ pop @extra_params } } else { @@ -169,9 +168,11 @@ sub forward { no warnings 'recursion'; - local $c->request->{arguments} = \@args; + my $orig_args = $c->request->arguments(); + $c->request->arguments(\@args); $action->dispatch( $c ); - + $c->request->arguments($orig_args); + return $c->state; } @@ -253,9 +254,10 @@ Find an dispatch type that matches $c->req->path, and set args from it. sub prepare_action { my ( $self, $c ) = @_; - my $path = $c->req->path; - my @path = split /\//, $c->req->path; - $c->req->args( \my @args ); + my $req = $c->req; + my $path = $req->path; + my @path = split /\//, $req->path; + $req->args( \my @args ); unshift( @path, '' ); # Root action @@ -278,10 +280,10 @@ sub prepare_action { unshift @args, $arg; } - s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg for grep { defined } @{$c->req->captures||[]}; + s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg for grep { defined } @{$req->captures||[]}; - $c->log->debug( 'Path is "' . $c->req->match . '"' ) - if ( $c->debug && $c->req->match ); + $c->log->debug( 'Path is "' . $req->match . '"' ) + if ( $c->debug && $req->match ); $c->log->debug( 'Arguments are "' . join( '/', @args ) . '"' ) if ( $c->debug && @args ); @@ -299,14 +301,14 @@ sub get_action { $namespace = join( "/", grep { length } split '/', $namespace || "" ); - return $self->_action_hash->{"$namespace/$name"}; + return $self->_action_hash->{"${namespace}/${name}"}; } =head2 $self->get_action_by_path( $path ); - + Returns the named action by its full path. -=cut +=cut sub get_action_by_path { my ( $self, $path ) = @_; @@ -351,6 +353,7 @@ sub get_containers { return reverse grep { defined } @containers, $self->_container_hash->{''}; + #return (split '/', $namespace); # isnt this more clear? my @parts = split '/', $namespace; } @@ -389,12 +392,13 @@ sub register { my $registered = $self->_registered_dispatch_types; - my $priv = 0; + #my $priv = 0; #seems to be unused foreach my $key ( keys %{ $action->attributes } ) { next if $key eq 'Private'; my $class = "Catalyst::DispatchType::$key"; unless ( $registered->{$class} ) { - eval "require $class"; + #some error checking rethrowing here wouldn't hurt. + eval { Class::MOP::load_class($class) }; push( @{ $self->_dispatch_types }, $class->new ) unless $@; $registered->{$class} = 1; } @@ -453,10 +457,6 @@ sub _find_or_create_namespace_node { sub setup_actions { my ( $self, $c ) = @_; - $self->_dispatch_types( [] ); - $self->_registered_dispatch_types( {} ); - $self->_method_action_class('Catalyst::Action'); - $self->_action_container_class('Catalyst::ActionContainer'); my @classes = $self->_load_dispatch_types( @{ $self->preload_dispatch_types } ); @@ -512,7 +512,8 @@ sub _load_dispatch_types { for my $type (@types) { my $class = ( $type =~ /^\+(.*)$/ ) ? $1 : "Catalyst::DispatchType::${type}"; - eval "require $class"; + + eval { Class::MOP::load_class($class) }; Catalyst::Exception->throw( message => qq/Couldn't load "$class"/ ) if $@; push @{ $self->_dispatch_types }, $class->new; @@ -523,6 +524,9 @@ sub _load_dispatch_types { return @loaded; } +no Moose; +__PACKAGE__->meta->make_immutable; + =head2 meta Provided by Moose