File Coverage

blib/lib/XML/Conf.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


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