File Coverage

blib/lib/Config/Constants/XML/SAX/Handler.pm
Criterion Covered Total %
statement 58 60 96.6
branch 28 34 82.3
condition n/a
subroutine 10 10 100.0
pod 5 5 100.0
total 101 109 92.6


line stmt bran cond sub pod time code
1             package Config::Constants::XML::SAX::Handler;
2              
3 9     9   59 use strict;
  9         67  
  9         395  
4 9     9   47 use warnings;
  9         14  
  9         393  
5              
6             our $VERSION = '0.03';
7              
8 9     9   45 use constant MAX_INCLUDE_DEPTH => 5;
  9         14  
  9         1385  
9              
10 9     9   68 use base 'XML::SAX::Base';
  9         15  
  9         15682  
11              
12             sub new {
13 8     8 1 21 my $class = shift;
14 8         81 my $self = $class->SUPER::new(@_);
15 8         737 $self->{_config} = undef;
16 8         20 $self->{_current_module} = undef;
17 8         53 $self->{_current_constant} = undef;
18 8         17 $self->{_constant_deferred} = 0;
19 8         18 $self->{_expected_type} = undef;
20 8         21 $self->{_current_text} = undef;
21 8         17 $self->{_include_depth} = 0;
22 8         27 return $self;
23             }
24              
25 7     7 1 376 sub config { (shift)->{_config} }
26              
27             sub start_element {
28 56     56 1 55356 my ($self, $el) = @_;
29 56         432 my $tag_name = lc($el->{Name});
30 56 100       242 if ($tag_name eq 'config') {
    100          
    100          
    50          
31 15 100       96 $self->{_config} = {} unless $self->{_config};
32             }
33             elsif ($tag_name eq 'include') {
34 8         26 my $path = $self->_get_value($el, 'path');
35 8 50       169 (-e $path)
36             || die "Cannot find include file at '$path'";
37 8 100       308 ($self->{_include_depth} < $self->MAX_INCLUDE_DEPTH)
38             || die "You have reached the max include depth";
39 7         24 $self->{_include_depth}++;
40 7         58 my $p = XML::SAX::ParserFactory->parser(Handler => $self);
41 7         3033 $p->parse_uri($path);
42             }
43             elsif ($tag_name eq 'module') {
44 14         275 $self->{_current_module} = $self->_get_value($el, 'name');
45 14 100       108 $self->{_config}->{$self->{_current_module}} = {}
46             unless exists $self->{_config}->{$self->{_current_module}};
47             }
48             elsif ($tag_name eq 'constant') {
49 19         49 $self->{_current_constant} = $self->_get_value($el, 'name');
50 19 100       58 if (defined($self->_get_value($el, 'value'))) {
51 16         35 $self->{_config}
52             ->{$self->{_current_module}}
53             ->{$self->{_current_constant}} = $self->_get_value($el, 'value')
54             }
55             else {
56 3         6 $self->{_expected_type} = $self->_get_value($el, 'type');
57 3         10 $self->{_constant_deferred} = 1;
58             }
59             }
60             else {
61 0         0 die "did not recognize the tag: $tag_name";
62             }
63             }
64              
65             sub end_element {
66 44     44 1 4530 my ($self, $el) = @_;
67 44 100       184 return unless lc($el->{Name}) eq 'constant';
68 19 100       86 return unless $self->{_constant_deferred};
69 3 50       8 ($self->{_current_text})
70             || die "We dont have anything to put into the constant '" . $self->{_current_constant} . "'";
71 3         13 $self->{_config}
72             ->{$self->{_current_module}}
73             ->{$self->{_current_constant}} = $self->{_current_text};
74 3         4 $self->{_current_text} = undef;
75 3         9 $self->{_constant_deferred} = 0;
76             }
77              
78             sub characters {
79 67     67 1 3779 my ($self, $el) = @_;
80 67         156 my $data = $el->{Data};
81 67 100       421 return if $data =~ /^\s+$/;
82 3 50       22 if ($self->{_expected_type}) {
83 3         199 my $value = eval $data;
84 3 50       11 die "eval of constant value failed: '$data' -> $@" if $@;
85 3 50       16 (UNIVERSAL::isa($value, $self->{_expected_type}))
86             || die "constant did not eval into the type we expected ($data); got : '$value' - expected: '" . $self->{_expected_type}. "'";
87 3         12 $self->{_current_text} = $value;
88             }
89             else {
90             # its just plain text
91 0         0 $self->{_current_text} = $data;
92             }
93             }
94              
95             sub _get_value {
96 79     79   115 my ($self, $el, $key) = @_;
97 79 100       237 return undef unless exists $el->{Attributes}->{'{}' . $key};
98 76         331 return $el->{Attributes}->{'{}' . $key}->{Value};
99             }
100              
101             1;
102              
103             __END__