refactor of namespace handling
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Dispatcher.pm
index 68fe551..5df4526 100644 (file)
@@ -15,6 +15,8 @@ use Text::SimpleTable;
 use Tree::Simple;
 use Tree::Simple::Visitor::FindByPath;
 
+use namespace::clean -except => 'meta';
+
 # Refactoring note:
 # do these belong as package vars or should we build these via a builder method?
 # See Catalyst-Plugin-Server for them being added to, which should be much less ugly.
@@ -26,7 +28,7 @@ our @PRELOAD = qw/Index Path Regex/;
 our @POSTLOAD = qw/Default/;
 
 # Note - see back-compat methods at end of file.
-has _tree => (is => 'rw');
+has _tree => (is => 'rw', builder => '_build__tree');
 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');
@@ -44,8 +46,6 @@ around qw/preload_dispatch_types postload_dispatch_types/ => sub {
     return $self->$orig(@_);
 };
 
-no Moose;
-
 =head1 NAME
 
 Catalyst::Dispatcher - The Catalyst Dispatcher
@@ -67,13 +67,13 @@ Construct a new dispatcher.
 
 =cut
 
-sub BUILD {
-  my ($self, $params) = @_;
+sub _build__tree {
+  my ($self) = @_;
 
   my $container =
     Catalyst::ActionContainer->new( { part => '/', actions => {} } );
 
-  $self->_tree( Tree::Simple->new( $container, Tree::Simple->ROOT ) );
+  return Tree::Simple->new($container, Tree::Simple->ROOT);
 }
 
 =head2 $self->preload_dispatch_types
@@ -236,6 +236,7 @@ Documented in L<Catalyst>
 
 sub forward {
     my $self = shift;
+    no warnings 'recursion';
     $self->_do_forward(forward => @_);
 }
 
@@ -253,9 +254,9 @@ sub _do_forward {
         return 0;
     }
 
-    no warnings 'recursion';
 
     local $c->request->{arguments} = $args;
+    no warnings 'recursion';
     $action->dispatch( $c );
 
     return $c->state;
@@ -307,40 +308,44 @@ sub _invoke_as_path {
     }
 }
 
-sub _find_component_class {
+sub _find_component {
     my ( $self, $c, $component ) = @_;
 
-    return ref($component)
-      || ref( $c->component($component) )
-      || $c->component($component);
+    # fugly, why doesn't ->component('MyApp') work?
+    return $c if ($component eq blessed($c));
+
+    return blessed($component)
+        ? $component
+        : $c->component($component);
 }
 
 sub _invoke_as_component {
-    my ( $self, $c, $component, $method ) = @_;
+    my ( $self, $c, $component_or_class, $method ) = @_;
 
-    my $class = $self->_find_component_class( $c, $component ) || return 0;
+    my $component = $self->_find_component($c, $component_or_class);
+    my $component_class = blessed $component || return 0;
 
-    if (my $code = $component_instance->can('action_for')) {
-        my $possible_action = $component_instance->$code($method);
+    if (my $code = $component_class->can('action_for')) {
+        my $possible_action = $component->$code($method);
         return $possible_action if $possible_action;
     }
 
-    if ( my $code = $class->can($method) ) {
+    if ( my $code = $component_class->can($method) ) {
         return $self->_method_action_class->new(
             {
                 name      => $method,
                 code      => $code,
-                reverse   => "$class->$method",
-                class     => $class,
+                reverse   => "$component_class->$method",
+                class     => $component_class,
                 namespace => Catalyst::Utils::class2prefix(
-                    $class, $c->config->{case_sensitive}
+                    $component_class, $c->config->{case_sensitive}
                 ),
             }
         );
     }
     else {
         my $error =
-          qq/Couldn't forward to "$class". Does not implement "$method"/;
+          qq/Couldn't forward to "$component_class". Does not implement "$method"/;
         $c->error($error);
         $c->log->debug($error)
           if $c->debug;
@@ -408,7 +413,7 @@ sub get_action {
 
 =head2 $self->get_action_by_path( $path ); 
 
-Returns the named action by its full path. 
+Returns the named action by its full private path.
 
 =cut
 
@@ -638,9 +643,8 @@ sub _load_dispatch_types {
 
     # Preload action types
     for my $type (@types) {
-        my $class =
-          ( $type =~ /^\+(.*)$/ ) ? $1 : "Catalyst::DispatchType::${type}";
-
+        my $class = Catalyst::Utils::resolve_namespace('Catalyst::DispatchType', $type);
+        
         eval { Class::MOP::load_class($class) };
         Catalyst::Exception->throw( message => qq/Couldn't load "$class"/ )
           if $@;
@@ -652,13 +656,18 @@ sub _load_dispatch_types {
     return @loaded;
 }
 
-# Dont document this until someone else is happy with beaviour. Ash 2009/03/16
+=head2 $self->dispatch_type( $type )
+
+Get the DispatchType object of the relevant type, i.e. passing C<$type> of
+C<Chained> would return a L<Catalyst::DispatchType::Chained> object (assuming
+of course it's being used.) 
+
+=cut
+
 sub dispatch_type {
     my ($self, $name) = @_;
 
-    unless ($name =~ s/^\+//) {
-        $name = "Catalyst::DispatchType::" . $name;
-    }
+    $name = Catalyst::Utils::resolve_namespace('Catalyst::DispatchType', $name);
 
     for (@{ $self->_dispatch_types }) {
         return $_ if ref($_) eq $name;
@@ -695,17 +704,18 @@ foreach my $public_method_name (qw/
         my %package_hash; # Only warn once per method, per package. These are infrequent enough that
                           # I haven't provided a way to disable them, patches welcome.
         $meta->add_before_method_modifier($public_method_name, sub {
-            my $class = blessed(shift);
-            $package_hash{$class}++ || do { 
-                warn("Class $class is calling the deprecated method Catalyst::Dispatcher::$public_method_name,\n"
-                    . "this will be removed in Catalyst 5.9X");
+            my $class = caller(2);
+            chomp($class);
+            $package_hash{$class}++ || do {
+                warn("Class $class is calling the deprecated method\n"
+                    . "  Catalyst::Dispatcher::$public_method_name,\n"
+                    . "  this will be removed in Catalyst 5.9X\n");
             };
         });
     }
 }
 # End 5.70 backwards compatibility hacks.
 
-no Moose;
 __PACKAGE__->meta->make_immutable;
 
 =head2 meta