File Coverage

blib/lib/XML/Conf.pm
Criterion Covered Total %
statement 106 125 84.8
branch 16 26 61.5
condition 3 8 37.5
subroutine 27 32 84.3
pod 0 6 0.0
total 152 197 77.1


line stmt bran cond sub pod time code
1             package XML::Conf;
2              
3 3     3   97580 use XML::Simple;
  3         28785  
  3         20  
4 3     3   250 use strict;
  3         6  
  3         74  
5 3     3   17 use warnings;
  3         6  
  3         129  
6 3     3   16 use vars qw($VERSION @ISA);
  3         5  
  3         161  
7 3     3   1569 use Tie::DeepTied;
  3         6514  
  3         91  
8 3     3   16 use Tie::Hash;
  3         4  
  3         54  
9 3     3   13 use Carp;
  3         3  
  3         2761  
10              
11             $VERSION = 0.07;
12              
13             sub new {
14 4     4 0 2195 my ($class, $filename, %opts) = @_;
15 4         7 my $xml;
16             my $fn;
17              
18 4 50       26 if (ref($filename) eq 'SCALAR') { #Internal use (TIEHASH)
    50          
19 0         0 $xml = $$filename;
20             } elsif ($filename =~ m/^\s*\<.*\>\s*$/s) { #internal use (TIEHASH)
21 0         0 $xml = $filename;
22             } else { #internal use (ReadConfig)
23 4 100 66     128 $filename = "./$filename" if ($filename !~ /^[\/\.]/ && -e "./$filename");
24 4 50       137 open(I, $filename) || croak "Could not open $filename: $!";
25 4         889 $xml = join("", );
26 4         140 close(I);
27 4         12 $fn = $filename;
28             }
29 4   50     24 my $hash = XML::Simple::XMLin($xml) || return undef;
30 4 100       280259 my $case = $opts{'case'}?$opts{'case'}:'_dummysub';
31             #my $case = $opts{'case'};
32 4 50       391 $hash = &_trans($hash, eval "sub { $case(\$_);} ") if ($case);
33             #$hash = &_trans($hash, $case) if ($case);
34 4         51 my $self = {'data' => $hash, 'case' => $case, 'fn' => $fn};
35 4         9 my $sig = $opts{'sig'};
36 4 50       14 if ($sig) {
37 0     0   0 $SIG{$sig} = sub { $self->ReadConfig; };
  0         0  
38             }
39 4         79 bless $self, $class;
40             }
41              
42             sub _dummysub {
43 66     66   159 my $val = shift;
44             }
45              
46             sub _trans {
47 64     64   87 my ($tree, $case) = @_;
48 64 100       956 return $tree unless (UNIVERSAL::isa($tree, 'HASH'));
49 20         15 my %hash;
50 3     3   18 no strict 'refs';
  3         3  
  3         225  
51 20         49 foreach (keys %$tree) {
52 60         98 $hash{ &$case($_) } = &_trans($tree->{$_}, $case);
53             }
54 3     3   15 use strict 'refs';
  3         3  
  3         1260  
55 20         288 \%hash;
56             }
57              
58             sub _val {
59 8     8   880 my $self = shift;
60 8         22 my $data = $self->{'data'};
61              
62 8         56 foreach (@_) {
63 8         19 $data = $data->{$_};
64             }
65 8 100       47 wantarray ? split("\n", $data) : $data;
66             }
67              
68             sub _setval {
69 3     3   1351 my $self = shift;
70 3         8 my $data = \$self->{'data'};
71 3         14 while (@_ > 1) {
72 5         21 $data = \($$data->{shift()});
73             }
74 3         12 $$data = shift;
75             }
76              
77             sub _newval {
78 0     0   0 my $self = shift;
79 0         0 $self->_setval(@_);
80             }
81              
82             sub _delval {
83 3     3   7 my $self = shift;
84 3         5 my $data = $self->{'data'};
85 3         12 while (@_ > 1) {
86 1         5 $data = $data->{shift()};
87             }
88 3         17 delete $data->{shift()};
89             }
90              
91             sub ReadConfig {
92 1     1 0 6 my $self = shift;
93 1         4 my $fn = $self->{'fn'};
94 1 50       2 return undef unless ($fn);
95 1         3 my $new = &new(__PACKAGE__, $fn, 'case' => $self->{'case'});
96 1         11 %$self = %$new;
97 1         14 1;
98             }
99              
100             sub Sections {
101 1     1 0 2 my $self = shift;
102 1         3 $self->Parameters(@_);
103             }
104              
105 0         0 sub Parameters {
106 2     2 0 3 my $self = shift;
107 2         4 my $val = $self->_val(@_);
108 2         3 my $case = $self->{'case'};
109 3     3   38 no strict 'refs';
  3         5  
  3         157  
110 2         4 map { &$case($_); } keys %$val;
  6         10  
111 3     3   13 use strict 'refs';
  3         3  
  3         2072  
112             }
113              
114             sub RewriteConfig {
115 1     1 0 2 my $self = shift;
116 1         1 my $fn = $self->{'fn'};
117 1 50       3 croak "No filename" unless ($fn);
118 1         3 $self->WriteConfig($fn);
119             }
120              
121             sub WriteConfig {
122 2     2 0 3 my ($self, $name) = @_;
123 2         6 my $xml = XMLout($self->{'data'}, xmldecl => 1);
124 2 50       1438 open(O, ">$name") || croak "Can't rewrite $name: $!";
125 2         15 print O $xml;
126 2         110 close(O);
127             }
128              
129             sub TIEHASH {
130 0     0   0 my $class = shift;
131 0         0 $class->new(@_);
132             }
133              
134             sub FETCH {
135 0     0   0 my ($self, $key) = @_;
136 0         0 my $val = $self->_val($key);
137 0 0 0     0 if (UNIVERSAL::isa($val, 'HASH') && !tied(%$val)) {
138 0         0 my %h = %$val;
139 0         0 tie %$val, 'Tie::StdHash', $self, $key;
140 0         0 %$val = %h;
141 0         0 tie %$val, 'Tie::DeepTied', $self, $key;
142             }
143 0         0 $val;
144             }
145              
146             sub STORE {
147 0     0   0 my ($self, $key, $val) = @_;
148 0         0 $self->_setval($key, $val);
149             }
150              
151             sub DELETE {
152 1     1   1 my ($self, $key) = @_;
153 1         3 $self->_delval($key);
154             }
155              
156             sub CLEAR {
157 1     1   2 my $self = shift;
158 1         8 $self->{'data'} = {};
159             }
160              
161             sub EXISTS {
162 2     2   202 my ($self, $key) = @_;
163 2         6 exists $self->{'data'}->{$key};
164             }
165              
166             sub FIRSTKEY {
167 3     3   167 my $self = shift;
168 3         1 keys %{$self->{'data'}};
  3         40  
169 3         4 each %{$self->{'data'}};
  3         10  
170             }
171              
172             sub NEXTKEY {
173 4     4   341 my $self = shift;
174 4         3 each %{$self->{'data'}};
  4         16  
175             }
176              
177             1;
178              
179             __END__