Path-AttrRouter

 view release on metacpan or  search on metacpan

lib/Path/AttrRouter.pm  view on Meta::CPAN

);

has action_class => (
    is      => 'rw',
    isa     => 'Str',
    default => 'Path::AttrRouter::Action',
);

has action_cache => (
    is  => 'rw',
    isa => 'Str',
);

has dispatch_types => (
    is      => 'rw',
    isa     => 'ArrayRef',
    lazy    => 1,
    default => sub {
        my $self = shift;

        my @types;
        for (qw/Path Regex Chained/) {
            my $class = "Path::AttrRouter::DispatchType::$_";
            $self->_ensure_class_loaded($class);
            push @types, $class->new;
        }

        \@types;
    },
);

has routing_table => (
    is      => 'rw',
    isa     => 'Object',
    lazy    => 1,
    default => sub {
        my $self = shift;
        $self->_ensure_class_loaded('Path::AttrRouter::AsciiTable');
        Path::AttrRouter::AsciiTable->new( router => $self );
    },
);

no Mouse;

sub BUILD {
    my $self = shift;

    $self->_ensure_class_loaded($self->action_class);

    if (my $cache_file = $self->action_cache) {
        $self->_load_cached_modules($cache_file);
    }
    else {
        $self->_load_modules;
    }
}

sub match {
    my ($self, $path, $condition) = @_;

    my @path = split m!/!, $path;
    unshift @path, '' unless @path;

    my ($action, @args, @captures);
 DESCEND:
    while (@path) {
        my $p = join '/', @path;
        $p =~ s!^/!!;

        for my $type (@{ $self->dispatch_types }) {
            $action = $type->match({
                path => $p,
                args => \@args,
                captures => \@captures,
                action_class => $self->action_class,
                $condition ? (%$condition) : (),
            });
            last DESCEND if $action;
        }

        my $arg = pop @path;
        $arg =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
        unshift @args, $arg;
    }

    s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg
        for grep {defined} @captures;

    if ($action) {
        # recreate controller instance if it is cached object
        unless (ref $action->controller) {
            $action->controller($self->_load_module($action->controller));
            for my $act (@{ $action->chain }) {
                $act->controller($self->_load_module($act->controller));
            }
        }

        return Path::AttrRouter::Match->new(
            action   => $action,
            args     => \@args,
            captures => \@captures,
            router   => $self,
        );
    }
    return;
}

sub print_table {
    print shift->routing_table->draw;
}

sub get_action {
    my ($self, $name, $namespace) = @_;
    return unless $name;

    $namespace ||= '';
    $namespace = '' if $namespace eq '/';

    my $container = $self->actions->{ $namespace } or return;
    my $action = $container->{ $name } or return;



( run in 0.893 second using v1.01-cache-2.11-cpan-71847e10f99 )