File Coverage

blib/lib/IOC/Visitor/ServiceLocator.pm
Criterion Covered Total %
statement 48 48 100.0
branch 14 14 100.0
condition 4 6 66.6
subroutine 8 8 100.0
pod 2 2 100.0
total 76 78 97.4


line stmt bran cond sub pod time code
1              
2             package IOC::Visitor::ServiceLocator;
3              
4 22     22   316 use strict;
  22         40  
  22         884  
5 22     22   124 use warnings;
  22         40  
  22         1105  
6              
7             our $VERSION = '0.02';
8              
9 22     22   131 use Scalar::Util qw(blessed);
  22         40  
  22         1251  
10              
11 22     22   148 use IOC::Interfaces;
  22         48  
  22         785  
12 22     22   117 use IOC::Exceptions;
  22         43  
  22         780  
13              
14 22     22   131 use base 'IOC::Visitor';
  22         49  
  22         40532  
15              
16             sub new {
17 40     40 1 9115 my ($_class, $path, $extra_args) = @_;
18 40 100       120 ($path)
19             || throw IOC::InsufficientArguments "You must provide an path to locate a container";
20 39   33     186 my $class = ref($_class) || $_class;
21 39         157 my $visitor = {
22             path => $path,
23             extra_args => $extra_args
24             };
25 39         441 bless($visitor, $class);
26 39         274 return $visitor;
27             }
28              
29             sub visit {
30 42     42 1 5283 my ($self, $container) = @_;
31 42 100 100     747 (blessed($container) && $container->isa('IOC::Container'))
32             || throw IOC::InsufficientArguments "You must provide an IOC::Container object as a sub-container";
33 38         55 my $service;
34 38 100       169 my @extra_args = (defined $self->{extra_args} ? @{$self->{extra_args}} : ());
  18         44  
35 38         201 my @path = grep { $_ } split /\// => $self->{path};
  80         189  
36 38         78 my $service_name = pop @path;
37 38 100       199 if ($self->{path} =~ /^\//) {
38             # start at the root
39 12         56 my $current = $container->findRootContainer();
40 12         30 foreach my $container_name (@path) {
41 15         26 eval {
42 15         55 $current = $current->getSubContainer($container_name);
43             };
44 15 100       743 throw IOC::UnableToLocateService "Could not locate the service at path '" . $self->{path} . "' failed at '$container_name'", $@ if $@;
45             }
46 11         43 $service = $current->get($service_name, @extra_args);
47             }
48             else {
49 26         49 my $current = $container;
50 26         54 foreach my $container_name (@path) {
51 15 100       166 if ($container_name eq '..') {
52 4         15 $current = $current->getParentContainer();
53             }
54             else {
55 11         17 eval {
56 11         44 $current = $current->getSubContainer($container_name);
57             };
58 11 100       67 throw IOC::UnableToLocateService "Could not locate the service at path '" . $self->{path} . "' failed at '$container_name'", $@ if $@;
59             }
60             }
61 25         98 $service = $current->get($service_name, @extra_args);
62             }
63 35         223 return $service;
64             }
65              
66             1;
67              
68             __END__