line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package OpenPlugin::Config; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# $Id: Config.pm,v 1.28 2003/04/28 17:43:48 andreychek Exp $ |
4
|
|
|
|
|
|
|
|
5
|
6
|
|
|
6
|
|
7911
|
use strict; |
|
6
|
|
|
|
|
16
|
|
|
6
|
|
|
|
|
831
|
|
6
|
6
|
|
|
6
|
|
41
|
use Cwd qw(); |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
131
|
|
7
|
6
|
|
|
6
|
|
9828
|
use Data::Dumper qw( Dumper ); |
|
6
|
|
|
|
|
66433
|
|
|
6
|
|
|
|
|
819
|
|
8
|
6
|
|
|
6
|
|
77
|
use File::Basename qw(); |
|
6
|
|
|
|
|
13
|
|
|
6
|
|
|
|
|
203
|
|
9
|
6
|
|
|
6
|
|
37
|
use Log::Log4perl qw( get_logger ); |
|
6
|
|
|
|
|
14
|
|
|
6
|
|
|
|
|
126
|
|
10
|
6
|
|
|
6
|
|
458
|
use OpenPlugin::Plugin; |
|
6
|
|
|
|
|
15
|
|
|
6
|
|
|
|
|
17858
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
@OpenPlugin::Config::ISA = qw( OpenPlugin::Plugin ); |
13
|
|
|
|
|
|
|
$OpenPlugin::Config::VERSION = sprintf("%d.%02d", q$Revision: 1.28 $ =~ /(\d+)\.(\d+)/); |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# Package var to keep track of files read in. Is there a better way to do |
16
|
|
|
|
|
|
|
# this? |
17
|
|
|
|
|
|
|
#%OpenPlugin::ConfigFiles = {}; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
my $logger = get_logger(); |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
######################################## |
22
|
|
|
|
|
|
|
# CLASS METHODS |
23
|
|
|
|
|
|
|
######################################## |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# This is the only place where we should have to specify information |
26
|
|
|
|
|
|
|
# that is normally in the driver map. Otherwise we have a |
27
|
|
|
|
|
|
|
# bootstrapping problem... |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
my %CONFIG_CLASS = ( |
30
|
|
|
|
|
|
|
conf => 'OpenPlugin::Config::Conf', |
31
|
|
|
|
|
|
|
ini => 'OpenPlugin::Config::Ini', |
32
|
|
|
|
|
|
|
perl => 'OpenPlugin::Config::Perl', |
33
|
|
|
|
|
|
|
xml => 'OpenPlugin::Config::XML', |
34
|
|
|
|
|
|
|
); |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
sub get_config_driver { |
38
|
13
|
|
|
13
|
0
|
137
|
my ( $class, $config_src, $config_type ) = @_; |
39
|
13
|
50
|
|
|
|
53
|
unless ( $config_type ) { |
40
|
13
|
|
|
|
|
193
|
( $config_type ) = $config_src =~ /\.(\w+)\s*$/; |
41
|
|
|
|
|
|
|
} |
42
|
13
|
|
|
|
|
95
|
return $CONFIG_CLASS{ lc $config_type }; |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
# Even if they're given a relative path, config implementations should |
47
|
|
|
|
|
|
|
# use this to get the full configuration directory and filename so |
48
|
|
|
|
|
|
|
# that 'Include' directives work as expected |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub find_config_location { |
51
|
12
|
|
|
12
|
0
|
28
|
my ( $class, $initial_filename, $other_root_dir ) = @_; |
52
|
12
|
|
|
|
|
62
|
$logger->info( "Finding configuration location from ($initial_filename)" ); |
53
|
|
|
|
|
|
|
|
54
|
12
|
100
|
|
|
|
198
|
return ( "", "" ) unless $initial_filename; |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# Get initial config dir, and untaint |
57
|
7
|
|
|
|
|
574
|
my $initial_dir = File::Basename::dirname( $initial_filename ); |
58
|
7
|
50
|
|
|
|
4771
|
( $initial_dir ) = $initial_dir =~ m/^(.*)$/ if -d $initial_dir; |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
# Get the config file name, and untaint |
61
|
7
|
|
|
|
|
265
|
my $config_file = File::Basename::basename( $initial_filename ); |
62
|
7
|
50
|
|
|
|
188
|
( $config_file ) = $config_file =~ m/^(.*)$/ if -f $initial_filename; |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
# Get the current working directory, and untaint |
65
|
7
|
|
|
|
|
80429
|
my $current_dir = Cwd::cwd; |
66
|
7
|
50
|
|
|
|
685
|
( $current_dir ) = $current_dir =~ m/^(.*)$/ if -d $current_dir; |
67
|
|
|
|
|
|
|
|
68
|
7
|
|
|
|
|
214
|
chdir( $initial_dir ); |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
# Get path to the current dir, and untaint |
71
|
7
|
|
|
|
|
118615
|
my $config_dir = Cwd::cwd; |
72
|
7
|
50
|
|
|
|
1247
|
( $config_dir ) = $config_dir =~ m/^(.*)$/ if -d $config_dir; |
73
|
|
|
|
|
|
|
|
74
|
7
|
|
|
|
|
137
|
chdir( $current_dir ); |
75
|
7
|
50
|
|
|
|
308
|
unless ( -f join( '/', $config_dir, $config_file ) ) { |
76
|
0
|
0
|
|
|
|
0
|
if ( -f join( '/', $other_root_dir, $config_file ) ) { |
77
|
0
|
|
|
|
|
0
|
$config_dir = $other_root_dir; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
} |
80
|
7
|
|
|
|
|
268
|
return ( $config_dir, $config_file ); |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
sub read { |
84
|
12
|
|
|
12
|
0
|
49
|
my ( $self, $data ) = @_; |
85
|
|
|
|
|
|
|
|
86
|
12
|
|
|
|
|
21
|
my ( $full_filename, $config ); |
87
|
12
|
100
|
|
|
|
58
|
if( ref $data ne "HASH" ) { |
88
|
7
|
|
33
|
|
|
244
|
$full_filename ||= join( '/', $self->{_m}{dir}, $self->{_m}{filename} ); |
89
|
7
|
|
|
|
|
196
|
$logger->info( "Trying to read file ($full_filename)" ); |
90
|
|
|
|
|
|
|
|
91
|
7
|
|
|
|
|
574
|
my $config_class = |
92
|
|
|
|
|
|
|
OpenPlugin::Config->get_config_driver( $full_filename, |
93
|
|
|
|
|
|
|
$self->{_m}{type} ); |
94
|
7
|
50
|
|
|
|
58
|
unless ( $config_class ) { |
95
|
0
|
|
|
|
|
0
|
die "Config is of unknown type! (Type: $self->{_m}{type} )"; |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# The config drivers are defined at the top of this file, and are not |
99
|
|
|
|
|
|
|
# tainted |
100
|
7
|
|
|
|
|
1656
|
eval "require $config_class"; |
101
|
7
|
|
|
|
|
163
|
$config = $config_class->get_config( $full_filename ); |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
else { |
104
|
5
|
|
|
|
|
12
|
$config = $data; |
105
|
|
|
|
|
|
|
} |
106
|
12
|
|
|
|
|
30
|
foreach my $key ( keys %{ $config } ) { |
|
12
|
|
|
|
|
60
|
|
107
|
19
|
|
|
|
|
79
|
$self->{$key} = $config->{$key}; |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
# Now see if there are any settings for 'Include' |
111
|
12
|
100
|
|
|
|
90
|
if ( $self->{include} ) { |
112
|
6
|
|
|
|
|
38
|
foreach my $src ( $self->get( 'include', 'src' ) ) { |
113
|
6
|
50
|
|
|
|
32
|
next unless ( $src ); |
114
|
6
|
|
|
|
|
163
|
$logger->info( "Including file ($src)." ); |
115
|
6
|
|
|
|
|
63
|
$self->include( $src ) ; |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
12
|
|
|
|
|
125
|
$logger->info( "Config file ($full_filename) read into object ok" ); |
120
|
|
|
|
|
|
|
|
121
|
12
|
|
|
|
|
567
|
return $self; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
######################################## |
126
|
|
|
|
|
|
|
# PLUGIN INTERFACE |
127
|
|
|
|
|
|
|
######################################## |
128
|
|
|
|
|
|
|
|
129
|
0
|
|
|
0
|
0
|
0
|
sub type { return 'config' } |
130
|
|
|
|
|
|
|
|
131
|
0
|
|
|
0
|
0
|
0
|
sub write {} |
132
|
|
|
|
|
|
|
|
133
|
6
|
|
|
6
|
0
|
98
|
sub meta_config_dir { return $_[0]->{_m}{dir} } |
134
|
0
|
|
|
0
|
0
|
0
|
sub meta_config_file { return $_[0]->{_m}{filename} } |
135
|
30
|
|
|
30
|
0
|
412
|
sub OP { return $_[0]->{_m}{OP} } |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub init { |
138
|
12
|
|
|
12
|
0
|
29
|
my ( $self, $params ) = @_; |
139
|
|
|
|
|
|
|
|
140
|
12
|
|
|
|
|
32
|
my $src = $params->{src}; |
141
|
12
|
|
|
|
|
23
|
my $dir = $params->{dir}; |
142
|
|
|
|
|
|
|
|
143
|
12
|
|
|
|
|
52
|
my ( $config_dir, $filename ) = $self->find_config_location( $src, $dir ); |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
# Keep track of what has been read in |
146
|
12
|
|
|
|
|
112
|
$self->{_m}{filename} = $filename; |
147
|
12
|
|
|
|
|
65
|
$self->{_m}{dir} = $config_dir; |
148
|
12
|
|
|
|
|
75
|
$self->{_m}{type} = $params->{type}; |
149
|
12
|
|
|
|
|
124
|
$self->{_m}{OP}{_toggle}{$filename} = 1; |
150
|
12
|
|
|
|
|
492
|
return $self; |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
sub sections { |
155
|
12
|
|
|
12
|
0
|
294
|
my ( $self ) = @_; |
156
|
12
|
|
|
|
|
31
|
return grep ! /^_m$/, sort keys %{ $self }; |
|
12
|
|
|
|
|
209
|
|
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
sub get { |
160
|
222
|
|
|
222
|
0
|
1217
|
my ( $self, $section, @p ) = @_; |
161
|
222
|
100
|
|
|
|
1345
|
my ( $sub_section, $param ) = ( $p[1] ) ? ( $p[0], $p[1] ) : ( undef, $p[0] ); |
162
|
222
|
100
|
|
|
|
1283
|
my $item = ( $sub_section ) |
163
|
|
|
|
|
|
|
? $self->{ $section }{ $sub_section }{ $param } |
164
|
|
|
|
|
|
|
: $self->{ $section }{ $param }; |
165
|
222
|
50
|
|
|
|
1289
|
return $item unless ( ref $item eq 'ARRAY' ); |
166
|
0
|
0
|
|
|
|
0
|
return wantarray ? @{ $item } : $item->[0]; |
|
0
|
|
|
|
|
0
|
|
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
sub set { |
170
|
216
|
|
|
216
|
0
|
407
|
my ( $self, $section, @p ) = @_; |
171
|
216
|
50
|
|
|
|
1676
|
my ( $sub_section, $param, $value ) = ( $p[2] ) ? ( $p[0], $p[1], $p[2] ) : ( undef, $p[0], $p[1] ); |
172
|
216
|
50
|
|
|
|
1522
|
return $self->{ $section }{ $sub_section }{ $param } = $value if ( $sub_section ); |
173
|
0
|
|
|
|
|
0
|
return $self->{ $section }{ $param } = $value |
174
|
|
|
|
|
|
|
} |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
sub delete { |
178
|
0
|
|
|
0
|
0
|
0
|
my ( $self, $section, @p ) = @_; |
179
|
0
|
0
|
|
|
|
0
|
my ( $sub_section, $param ) = ( $p[1] ) ? ( $p[0], $p[1] ) : ( undef, $p[0] ); |
180
|
0
|
0
|
|
|
|
0
|
if ( $sub_section ) { |
|
|
0
|
|
|
|
|
|
181
|
0
|
|
|
|
|
0
|
$logger->info( "Deleting ($param) from sub-section ($section)($sub_section)" ); |
182
|
0
|
|
|
|
|
0
|
return delete $self->{ $section }{ $sub_section }{ $param }; |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
elsif ( $param ) { |
185
|
0
|
|
|
|
|
0
|
$logger->info( "Deleting ($param) from section ($section)" ); |
186
|
0
|
|
|
|
|
0
|
return delete $self->{ $section }{ $param }; |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
else { |
189
|
0
|
|
|
|
|
0
|
$logger->info( "Deleting section ($section)" ); |
190
|
0
|
|
|
|
|
0
|
return delete $self->{ $section }; |
191
|
|
|
|
|
|
|
} |
192
|
|
|
|
|
|
|
} |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
# Allow a configuration to 'include' another configuration file -- it |
196
|
|
|
|
|
|
|
# might be one of a different type too, so an INI file can include an |
197
|
|
|
|
|
|
|
# XML file, etc. |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
sub include { |
200
|
6
|
|
|
6
|
0
|
14
|
my ( $self, $config_src ) = @_; |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
# History tends to "repeat" itself if we don't learn it the first time ;-) |
203
|
6
|
50
|
|
|
|
20
|
if ( $self->OP->{_toggle}{$config_src} ) { |
204
|
0
|
|
|
|
|
0
|
$logger->warn("Attempt to include ($config_src), which is already loaded!"); |
205
|
0
|
|
|
|
|
0
|
return; |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
# Flag this so we can tell we started processing this config |
209
|
6
|
|
|
|
|
25
|
$self->OP->{_toggle}{$config_src} = 1; |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
# Find out what type of configuration this is and read it in |
212
|
6
|
|
|
|
|
99
|
my $config_class = $self->get_config_driver( $config_src ); |
213
|
6
|
50
|
|
|
|
102
|
unless ( $config_class ) { |
214
|
0
|
|
|
|
|
0
|
die "Configuration ($config_src) cannot be included -- no valid ", |
215
|
|
|
|
|
|
|
"configuration class found.\n"; |
216
|
|
|
|
|
|
|
} |
217
|
6
|
|
|
|
|
40
|
$logger->info( "Trying to use class ($config_class) for included ", |
218
|
|
|
|
|
|
|
"config ($config_src)" ); |
219
|
6
|
|
|
|
|
652
|
eval "require $config_class"; |
220
|
|
|
|
|
|
|
|
221
|
6
|
|
|
|
|
55
|
my $include_config = OpenPlugin::Plugin->new( "config", $self, { |
222
|
|
|
|
|
|
|
src => $config_src, |
223
|
|
|
|
|
|
|
dir => $self->meta_config_dir })->read; |
224
|
|
|
|
|
|
|
|
225
|
6
|
50
|
|
|
|
95
|
if( $logger->is_debug ) { |
226
|
0
|
|
|
|
|
0
|
$logger->debug( "Included config: ", Dumper( $include_config ) ); |
227
|
|
|
|
|
|
|
} |
228
|
|
|
|
|
|
|
|
229
|
6
|
|
|
|
|
137
|
$logger->info( "Sections of included config: ", join( ', ', $include_config->sections ) ); |
230
|
6
|
|
|
|
|
1147
|
foreach my $section ( $include_config->sections ) { |
231
|
6
|
|
|
|
|
48
|
$logger->info( "Entering section ($section) of included config" ); |
232
|
6
|
50
|
|
|
|
319
|
next unless ( ref $include_config->{ $section } eq 'HASH' ); |
233
|
6
|
|
|
|
|
16
|
foreach my $param ( keys %{ $include_config->{ $section } } ) { |
|
6
|
|
|
|
|
44
|
|
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
# This section has a subsection, and $param is the subsection title |
236
|
|
|
|
|
|
|
|
237
|
72
|
50
|
|
|
|
561
|
if ( ref $include_config->{ $section }{ $param } eq 'HASH' ) { |
238
|
72
|
|
|
|
|
1488
|
$logger->info( "($section)($param) is a hashref -- read in one at a time" ); |
239
|
72
|
|
|
|
|
498
|
foreach my $sub_param ( keys %{ $include_config->{ $section }{ $param } } ) { |
|
72
|
|
|
|
|
281
|
|
240
|
216
|
|
|
|
|
871
|
$self->set( $section, $param, $sub_param, |
241
|
|
|
|
|
|
|
$include_config->get( $section, $param, $sub_param ) ); |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
else { |
245
|
0
|
|
|
|
|
0
|
$logger->info( "($section)($param) is a value" ); |
246
|
0
|
|
|
|
|
0
|
$self->set( $section, $param, $include_config->get( $section, $param ) ); |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
} |
249
|
|
|
|
|
|
|
} |
250
|
6
|
|
|
|
|
1022
|
return $include_config; |
251
|
|
|
|
|
|
|
} |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
1; |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
__END__ |