line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# |
2
|
|
|
|
|
|
|
# This file is part of Config-Model |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# This software is Copyright (c) 2005-2022 by Dominique Dumont. |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
# This is free software, licensed under: |
7
|
|
|
|
|
|
|
# |
8
|
|
|
|
|
|
|
# The GNU Lesser General Public License, Version 2.1, February 1999 |
9
|
|
|
|
|
|
|
# |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
use v5.20; |
12
|
59
|
|
|
59
|
|
699
|
|
|
59
|
|
|
|
|
192
|
|
13
|
|
|
|
|
|
|
use strict; |
14
|
59
|
|
|
59
|
|
293
|
use warnings; |
|
59
|
|
|
|
|
113
|
|
|
59
|
|
|
|
|
1174
|
|
15
|
59
|
|
|
59
|
|
254
|
use feature "switch"; |
|
59
|
|
|
|
|
122
|
|
|
59
|
|
|
|
|
1544
|
|
16
|
59
|
|
|
59
|
|
303
|
|
|
59
|
|
|
|
|
113
|
|
|
59
|
|
|
|
|
4871
|
|
17
|
|
|
|
|
|
|
use Mouse; |
18
|
59
|
|
|
59
|
|
408
|
use Mouse::Util::TypeConstraints; |
|
59
|
|
|
|
|
131
|
|
|
59
|
|
|
|
|
441
|
|
19
|
59
|
|
|
59
|
|
24125
|
use MouseX::StrictConstructor; |
|
59
|
|
|
|
|
123
|
|
|
59
|
|
|
|
|
1314
|
|
20
|
59
|
|
|
59
|
|
5672
|
|
|
59
|
|
|
|
|
132
|
|
|
59
|
|
|
|
|
451
|
|
21
|
|
|
|
|
|
|
use Parse::RecDescent 1.90.0; |
22
|
59
|
|
|
59
|
|
68727
|
|
|
59
|
|
|
|
|
2048744
|
|
|
59
|
|
|
|
|
372
|
|
23
|
|
|
|
|
|
|
use Data::Dumper (); |
24
|
59
|
|
|
59
|
|
2862
|
use Config::Model::Exception; |
|
59
|
|
|
|
|
1285
|
|
|
59
|
|
|
|
|
878
|
|
25
|
59
|
|
|
59
|
|
278
|
use Config::Model::ValueComputer; |
|
59
|
|
|
|
|
1312
|
|
|
59
|
|
|
|
|
2509
|
|
26
|
59
|
|
|
59
|
|
30288
|
use Config::Model::IdElementReference; |
|
59
|
|
|
|
|
173
|
|
|
59
|
|
|
|
|
1915
|
|
27
|
59
|
|
|
59
|
|
25262
|
use Config::Model::Warper; |
|
59
|
|
|
|
|
158
|
|
|
59
|
|
|
|
|
1822
|
|
28
|
59
|
|
|
59
|
|
28319
|
use Log::Log4perl qw(get_logger :levels); |
|
59
|
|
|
|
|
186
|
|
|
59
|
|
|
|
|
2197
|
|
29
|
59
|
|
|
59
|
|
438
|
use Scalar::Util qw/weaken/; |
|
59
|
|
|
|
|
100
|
|
|
59
|
|
|
|
|
357
|
|
30
|
59
|
|
|
59
|
|
6735
|
use Carp; |
|
59
|
|
|
|
|
115
|
|
|
59
|
|
|
|
|
2788
|
|
31
|
59
|
|
|
59
|
|
293
|
use Storable qw/dclone/; |
|
59
|
|
|
|
|
96
|
|
|
59
|
|
|
|
|
2792
|
|
32
|
59
|
|
|
59
|
|
311
|
use Path::Tiny; |
|
59
|
|
|
|
|
182
|
|
|
59
|
|
|
|
|
2163
|
|
33
|
59
|
|
|
59
|
|
371
|
use List::MoreUtils qw(any) ; |
|
59
|
|
|
|
|
128
|
|
|
59
|
|
|
|
|
2675
|
|
34
|
59
|
|
|
59
|
|
364
|
|
|
59
|
|
|
|
|
103
|
|
|
59
|
|
|
|
|
470
|
|
35
|
|
|
|
|
|
|
extends qw/Config::Model::AnyThing/; |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
with "Config::Model::Role::WarpMaster"; |
38
|
|
|
|
|
|
|
with "Config::Model::Role::Grab"; |
39
|
|
|
|
|
|
|
with "Config::Model::Role::HelpAsText"; |
40
|
|
|
|
|
|
|
with "Config::Model::Role::ComputeFunction"; |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
use feature qw/postderef signatures/; |
43
|
59
|
|
|
59
|
|
36867
|
no warnings qw/experimental::postderef experimental::smartmatch experimental::signatures/; |
|
59
|
|
|
|
|
118
|
|
|
59
|
|
|
|
|
3039
|
|
44
|
59
|
|
|
59
|
|
324
|
|
|
59
|
|
|
|
|
143
|
|
|
59
|
|
|
|
|
424364
|
|
45
|
|
|
|
|
|
|
my $logger = get_logger("Tree::Element::Value"); |
46
|
|
|
|
|
|
|
my $user_logger = get_logger("User"); |
47
|
|
|
|
|
|
|
my $change_logger = get_logger("Anything::Change"); |
48
|
|
|
|
|
|
|
my $fix_logger = get_logger("Anything::Fix"); |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
our $nowarning = 0; # global variable to silence warnings. Only used for tests |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
enum ValueType => qw/boolean enum uniline string integer number reference file dir/; |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
has fixes => ( is => 'rw', isa => 'ArrayRef', default => sub { [] } ); |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
has [qw/warp compute computed_refer_to backup migrate_from/] => |
57
|
|
|
|
|
|
|
( is => 'rw', isa => 'Maybe[HashRef]' ); |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
has compute_obj => ( |
60
|
|
|
|
|
|
|
is => 'ro', |
61
|
|
|
|
|
|
|
isa => 'Maybe[Config::Model::ValueComputer]', |
62
|
|
|
|
|
|
|
builder => '_build_compute_obj', |
63
|
|
|
|
|
|
|
lazy => 1 |
64
|
|
|
|
|
|
|
); |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
has [qw/write_as/] => ( is => 'rw', isa => 'Maybe[ArrayRef]' ); |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
has [qw/refer_to _data replace_follow/] => ( is => 'rw', isa => 'Maybe[Str]' ); |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
has value_type => ( is => 'rw', isa => 'ValueType' ); |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
my @common_int_params = qw/min max mandatory /; |
73
|
|
|
|
|
|
|
has \@common_int_params => ( is => 'ro', isa => 'Maybe[Int]' ); |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
my @common_hash_params = qw/replace assert warn_if_match warn_unless_match warn_if warn_unless help/; |
76
|
|
|
|
|
|
|
has \@common_hash_params => ( is => 'ro', isa => 'Maybe[HashRef]' ); |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
my @common_list_params = qw/choice/; |
79
|
|
|
|
|
|
|
has \@common_list_params => ( is => 'ro', isa => 'Maybe[ArrayRef]' ); |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
my @common_str_params = qw/default upstream_default convert match grammar warn/; |
82
|
|
|
|
|
|
|
has \@common_str_params => ( is => 'ro', isa => 'Maybe[Str]' ); |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
my @warp_accessible_params = |
85
|
|
|
|
|
|
|
( @common_int_params, @common_str_params, @common_list_params, @common_hash_params ); |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
my @allowed_warp_params = ( @warp_accessible_params, qw/level help/ ); |
88
|
|
|
|
|
|
|
my @backup_list = ( @allowed_warp_params, qw/migrate_from/ ); |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
has compute_is_upstream_default => |
91
|
|
|
|
|
|
|
( is => 'ro', isa => 'Bool', lazy => 1, builder => '_compute_is_upstream_default' ); |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
my $self = shift; |
94
|
|
|
|
|
|
|
return 0 unless defined $self->compute; |
95
|
2752
|
|
|
2752
|
|
4179
|
return $self->compute_obj->use_as_upstream_default; |
96
|
2752
|
100
|
|
|
|
11592
|
} |
97
|
44
|
|
|
|
|
273
|
|
98
|
|
|
|
|
|
|
has compute_is_default => |
99
|
|
|
|
|
|
|
( is => 'ro', isa => 'Bool', lazy => 1, builder => '_compute_is_default' ); |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
my $self = shift; |
102
|
|
|
|
|
|
|
return 0 unless defined $self->compute; |
103
|
|
|
|
|
|
|
return !$self->compute_obj->use_as_upstream_default; |
104
|
3089
|
|
|
3089
|
|
5168
|
} |
105
|
3089
|
100
|
|
|
|
15677
|
|
106
|
45
|
|
|
|
|
209
|
has error_list => ( |
107
|
|
|
|
|
|
|
is => 'ro', |
108
|
|
|
|
|
|
|
isa => 'ArrayRef', |
109
|
|
|
|
|
|
|
default => sub { [] }, |
110
|
|
|
|
|
|
|
traits => ['Array'], |
111
|
|
|
|
|
|
|
handles => { |
112
|
|
|
|
|
|
|
add_error => 'push', |
113
|
|
|
|
|
|
|
clear_errors => 'clear', |
114
|
|
|
|
|
|
|
has_error => 'count', |
115
|
|
|
|
|
|
|
all_errors => 'elements', |
116
|
|
|
|
|
|
|
is_ok => 'is_empty' |
117
|
|
|
|
|
|
|
} ); |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
my $msg = ''; |
120
|
|
|
|
|
|
|
if ($self->has_error) { |
121
|
|
|
|
|
|
|
my @add; |
122
|
43
|
|
|
43
|
1
|
746
|
push @add, $self->compute_obj->compute_info if $self->compute_obj; |
|
43
|
|
|
|
|
77
|
|
|
43
|
|
|
|
|
67
|
|
123
|
43
|
|
|
|
|
86
|
push @add, $self->{_migrate_from}->compute_info if $self->{_migrate_from}; |
124
|
43
|
100
|
|
|
|
135
|
$msg = join("\n", $self->all_errors, @add); |
125
|
42
|
|
|
|
|
307
|
} |
126
|
42
|
100
|
|
|
|
203
|
return $msg; |
127
|
42
|
50
|
|
|
|
128
|
} |
128
|
42
|
|
|
|
|
417
|
|
129
|
|
|
|
|
|
|
has warning_list => ( |
130
|
43
|
|
|
|
|
778
|
is => 'ro', |
131
|
|
|
|
|
|
|
isa => 'ArrayRef', |
132
|
|
|
|
|
|
|
default => sub { [] }, |
133
|
|
|
|
|
|
|
traits => ['Array'], |
134
|
|
|
|
|
|
|
handles => { |
135
|
|
|
|
|
|
|
add_warning => 'push', |
136
|
|
|
|
|
|
|
clear_warnings => 'clear', |
137
|
|
|
|
|
|
|
warning_msg => [ join => "\n\t" ], |
138
|
|
|
|
|
|
|
has_warning => 'count', |
139
|
|
|
|
|
|
|
has_warnings => 'count', |
140
|
|
|
|
|
|
|
all_warnings => 'elements', |
141
|
|
|
|
|
|
|
} ); |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
# as some information must be backed up even though they are not |
144
|
|
|
|
|
|
|
# attributes, we cannot move code below in BUILD. |
145
|
|
|
|
|
|
|
around BUILDARGS => sub ($orig, $class, %args) { |
146
|
|
|
|
|
|
|
my %h = map { ( $_ => $args{$_} ); } grep { defined $args{$_} } @backup_list; |
147
|
|
|
|
|
|
|
return $class->$orig( backup => dclone( \%h ), %args ); |
148
|
|
|
|
|
|
|
}; |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
my $self = shift; |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
$self->set_properties(); # set will use backup data |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# used when self is a warped slave |
155
|
3428
|
|
|
3428
|
1
|
5539
|
if ( my $warp_info = $self->warp ) { |
156
|
|
|
|
|
|
|
$self->{warper} = Config::Model::Warper->new( |
157
|
3428
|
|
|
|
|
9272
|
warped_object => $self, |
158
|
|
|
|
|
|
|
%$warp_info, |
159
|
|
|
|
|
|
|
allowed => \@allowed_warp_params |
160
|
3426
|
100
|
|
|
|
10494
|
); |
161
|
300
|
|
|
|
|
6839
|
} |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
$self->_init; |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
return $self; |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
3425
|
|
|
|
|
10647
|
override 'needs_check' => sub ($self, @args) { |
169
|
|
|
|
|
|
|
if ($self->instance->layered) { |
170
|
3423
|
|
|
|
|
20907
|
# don't check value and don't store value in layered mode |
171
|
|
|
|
|
|
|
return 0; |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
elsif (@args) { |
174
|
|
|
|
|
|
|
return super(); |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
else { |
177
|
|
|
|
|
|
|
# some items like idElementReference are too complex to propagate |
178
|
|
|
|
|
|
|
# a change notification back to the value using them. So an error or |
179
|
|
|
|
|
|
|
# warning must always be rechecked. |
180
|
|
|
|
|
|
|
return ($self->value_type eq 'reference' or super()) ; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
}; |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
around notify_change => sub ($orig, $self, %args) { |
185
|
|
|
|
|
|
|
my $check_done = $args{check_done} || 0; |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
return if $self->instance->initial_load and not $args{really}; |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
if ($change_logger->is_trace) { |
190
|
|
|
|
|
|
|
my @a = map { ( $_ => $args{$_} // '<undef>' ); } sort keys %args; |
191
|
|
|
|
|
|
|
$change_logger->trace( "called while needs_check is ", |
192
|
|
|
|
|
|
|
$self->needs_check, " for ", $self->name, " with ", join( ' ', @a ) ); |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
$self->needs_check(1) unless $check_done; |
196
|
|
|
|
|
|
|
{ |
197
|
|
|
|
|
|
|
croak "needless change with $args{new}" |
198
|
|
|
|
|
|
|
if defined $args{old} |
199
|
|
|
|
|
|
|
and defined $args{new} |
200
|
|
|
|
|
|
|
and $args{old} eq $args{new}; |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
$args{new} = $self->map_write_as( $args{new} ); |
203
|
|
|
|
|
|
|
$args{old} = $self->map_write_as( $args{old} ); |
204
|
|
|
|
|
|
|
$self->$orig( %args, value_type => $self->value_type ); |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
# shake all warped or computed objects that depends on me |
207
|
|
|
|
|
|
|
foreach my $s ( $self->get_depend_slave ) { |
208
|
|
|
|
|
|
|
$change_logger->debug( "calling needs_check on slave ", $s->name ) |
209
|
|
|
|
|
|
|
if $change_logger->is_debug; |
210
|
|
|
|
|
|
|
$s->needs_check(1); |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
return; |
213
|
|
|
|
|
|
|
}; |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
# internal method |
216
|
|
|
|
|
|
|
my ( $self, $arg_ref ) = @_; |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
if ( exists $arg_ref->{built_in} ) { |
219
|
|
|
|
|
|
|
$arg_ref->{upstream_default} = delete $arg_ref->{built_in}; |
220
|
|
|
|
|
|
|
warn $self->name, " warning: deprecated built_in parameter, ", "use upstream_default\n"; |
221
|
|
|
|
|
|
|
} |
222
|
3974
|
|
|
3974
|
0
|
7119
|
|
223
|
|
|
|
|
|
|
if ( defined $arg_ref->{default} and defined $arg_ref->{upstream_default} ) { |
224
|
3974
|
50
|
|
|
|
8151
|
Config::Model::Exception::Model->throw( |
225
|
0
|
|
|
|
|
0
|
object => $self, |
226
|
0
|
|
|
|
|
0
|
error => "Cannot specify both 'upstream_default' and " . "'default' parameters", |
227
|
|
|
|
|
|
|
); |
228
|
|
|
|
|
|
|
} |
229
|
3974
|
50
|
66
|
|
|
10058
|
|
230
|
0
|
|
|
|
|
0
|
foreach my $item (qw/upstream_default default/) { |
231
|
|
|
|
|
|
|
my $def = delete $arg_ref->{$item}; |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
next unless defined $def; |
234
|
|
|
|
|
|
|
$self->transform_boolean( \$def ) if $self->value_type eq 'boolean'; |
235
|
|
|
|
|
|
|
|
236
|
3974
|
|
|
|
|
7435
|
# will check default value |
237
|
7948
|
|
|
|
|
12154
|
$self->check_value( value => $def ); |
238
|
|
|
|
|
|
|
Config::Model::Exception::Model->throw( |
239
|
7948
|
100
|
|
|
|
15234
|
object => $self, |
240
|
648
|
100
|
|
|
|
2363
|
error => "Wrong $item value\n\t" . $self->error_msg |
241
|
|
|
|
|
|
|
) if $self->has_error; |
242
|
|
|
|
|
|
|
|
243
|
648
|
|
|
|
|
2323
|
$logger->debug( "Set $item value for ", $self->name, "" ); |
244
|
648
|
100
|
|
|
|
2024
|
|
245
|
|
|
|
|
|
|
$self->{$item} = $def; |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
return; |
248
|
|
|
|
|
|
|
} |
249
|
646
|
|
|
|
|
5663
|
|
250
|
|
|
|
|
|
|
# set up relation between objects required by the compute constructor |
251
|
646
|
|
|
|
|
4824
|
# parameters |
252
|
|
|
|
|
|
|
my $self = shift; |
253
|
3972
|
|
|
|
|
5447
|
|
254
|
|
|
|
|
|
|
$logger->trace("called"); |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
my $c_info = $self->compute; |
257
|
|
|
|
|
|
|
return unless $c_info; |
258
|
|
|
|
|
|
|
|
259
|
1608
|
|
|
1608
|
|
2648
|
my @compute_data; |
260
|
|
|
|
|
|
|
foreach ( keys %$c_info ) { |
261
|
1608
|
|
|
|
|
4508
|
push @compute_data, $_, $c_info->{$_} if defined $c_info->{$_}; |
262
|
|
|
|
|
|
|
} |
263
|
1608
|
|
|
|
|
13230
|
|
264
|
1608
|
100
|
|
|
|
8288
|
my $ret = Config::Model::ValueComputer->new( |
265
|
|
|
|
|
|
|
@compute_data, |
266
|
45
|
|
|
|
|
72
|
value_object => $self, |
267
|
45
|
|
|
|
|
233
|
value_type => $self->{value_type}, |
268
|
98
|
50
|
|
|
|
333
|
); |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
# resolve any recursive variables before registration |
271
|
|
|
|
|
|
|
my $v = $ret->compute_variables; |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
$self->register_in_other_value($v); |
274
|
|
|
|
|
|
|
$logger->trace("done"); |
275
|
45
|
|
|
|
|
969
|
return $ret; |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
|
278
|
45
|
|
|
|
|
237
|
my $self = shift; |
279
|
|
|
|
|
|
|
my $var = shift; |
280
|
45
|
|
|
|
|
207
|
|
281
|
44
|
|
|
|
|
137
|
# register compute or refer_to dependency. This info may be used |
282
|
44
|
|
|
|
|
937
|
# by other tools |
283
|
|
|
|
|
|
|
foreach my $path ( values %$var ) { |
284
|
|
|
|
|
|
|
if ( defined $path and not ref $path ) { |
285
|
|
|
|
|
|
|
|
286
|
49
|
|
|
49
|
0
|
84
|
# is ref during test case |
287
|
49
|
|
|
|
|
77
|
#print "path is '$path'\n"; |
288
|
|
|
|
|
|
|
next if $path =~ /\$/; # next if path also contain a variable |
289
|
|
|
|
|
|
|
my $master = $self->grab($path); |
290
|
|
|
|
|
|
|
next unless $master->can('register_dependency'); |
291
|
49
|
|
|
|
|
130
|
$master->register_dependency($self); |
292
|
45
|
100
|
66
|
|
|
209
|
} |
293
|
|
|
|
|
|
|
} |
294
|
|
|
|
|
|
|
return; |
295
|
|
|
|
|
|
|
} |
296
|
43
|
50
|
|
|
|
130
|
|
297
|
43
|
|
|
|
|
145
|
# internal |
298
|
42
|
50
|
|
|
|
232
|
my $self = shift; |
299
|
42
|
|
|
|
|
135
|
$logger->trace("called"); |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
my $result = $self->compute_obj->compute; |
302
|
48
|
|
|
|
|
83
|
|
303
|
|
|
|
|
|
|
# check if the computed result fits with the constraints of the |
304
|
|
|
|
|
|
|
# Value model, but don't check if it's mandatory |
305
|
|
|
|
|
|
|
my ($value, $error, $warn) = $self->_check_value(value => $result); |
306
|
|
|
|
|
|
|
|
307
|
107
|
|
|
107
|
0
|
1576
|
if ( scalar $error->@* ) { |
308
|
107
|
|
|
|
|
271
|
my $error = join("\n", (@$error, $self->compute_info)); |
309
|
|
|
|
|
|
|
|
310
|
107
|
|
|
|
|
977
|
Config::Model::Exception::WrongValue->throw( |
311
|
|
|
|
|
|
|
object => $self, |
312
|
|
|
|
|
|
|
error => "computed value error:\n\t" . $error |
313
|
|
|
|
|
|
|
); |
314
|
107
|
|
|
|
|
342
|
} |
315
|
|
|
|
|
|
|
|
316
|
107
|
100
|
|
|
|
282
|
$logger->trace("done"); |
317
|
3
|
|
|
|
|
14
|
return $result; |
318
|
|
|
|
|
|
|
} |
319
|
3
|
|
|
|
|
29
|
|
320
|
|
|
|
|
|
|
# internal, used to generate error messages |
321
|
|
|
|
|
|
|
my $self = shift; |
322
|
|
|
|
|
|
|
return $self->compute_obj->compute_info; |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
|
325
|
104
|
|
|
|
|
269
|
my ( $self, $arg_ref ) = @_; |
326
|
104
|
|
|
|
|
828
|
|
327
|
|
|
|
|
|
|
my $mig_ref = delete $arg_ref->{migrate_from}; |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
if ( ref($mig_ref) eq 'HASH' ) { |
330
|
|
|
|
|
|
|
$self->migrate_from($mig_ref); |
331
|
3
|
|
|
3
|
0
|
5
|
} |
332
|
3
|
|
|
|
|
12
|
else { |
333
|
|
|
|
|
|
|
Config::Model::Exception::Model->throw( |
334
|
|
|
|
|
|
|
object => $self, |
335
|
|
|
|
|
|
|
error => "migrate_from value must be a hash ref not $mig_ref" |
336
|
13
|
|
|
13
|
0
|
34
|
); |
337
|
|
|
|
|
|
|
} |
338
|
13
|
|
|
|
|
31
|
|
339
|
|
|
|
|
|
|
my @migrate_data; |
340
|
13
|
50
|
|
|
|
43
|
foreach (qw/formula variables replace use_eval undef_is/) { |
341
|
13
|
|
|
|
|
59
|
push @migrate_data, $_, $mig_ref->{$_} if defined $mig_ref->{$_}; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
|
344
|
0
|
|
|
|
|
0
|
$self->{_migrate_from} = Config::Model::ValueComputer->new( |
345
|
|
|
|
|
|
|
@migrate_data, |
346
|
|
|
|
|
|
|
value_object => $self, |
347
|
|
|
|
|
|
|
value_type => $self->{value_type} ); |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
# resolve any recursive variables before registration |
350
|
13
|
|
|
|
|
26
|
my $v = $self->{_migrate_from}->compute_variables; |
351
|
13
|
|
|
|
|
38
|
return; |
352
|
65
|
100
|
|
|
|
153
|
} |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
# FIXME: should it be used only once ??? |
355
|
|
|
|
|
|
|
my $self = shift; |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
# migrate value is always used as a scalar, even in list |
358
|
13
|
|
|
|
|
295
|
# context. Not returning undef would break a hash assignment done |
359
|
|
|
|
|
|
|
# with something like: |
360
|
|
|
|
|
|
|
# my %args = (value => $obj->migrate_value, fix => 1). |
361
|
13
|
|
|
|
|
74
|
|
362
|
13
|
|
|
|
|
56
|
## no critic(Subroutines::ProhibitExplicitReturnUndef) |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
return undef if $self->{migration_done}; |
365
|
|
|
|
|
|
|
return undef if $self->instance->initial_load; |
366
|
|
|
|
|
|
|
$self->{migration_done} = 1; |
367
|
29
|
|
|
29
|
0
|
51
|
|
368
|
|
|
|
|
|
|
# avoid warning when reading deprecated values |
369
|
|
|
|
|
|
|
my $result = $self->{_migrate_from}->compute( check => 'skip' ); |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
return undef unless defined $result; |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
# check if the migrated result fits with the constraints of the |
374
|
|
|
|
|
|
|
# Value object |
375
|
|
|
|
|
|
|
my $ok = $self->check_value( value => $result ); |
376
|
29
|
100
|
|
|
|
87
|
|
377
|
19
|
100
|
|
|
|
105
|
#print "check result: $ok\n"; |
378
|
13
|
|
|
|
|
36
|
if ( not $ok ) { |
379
|
|
|
|
|
|
|
Config::Model::Exception::WrongValue->throw( |
380
|
|
|
|
|
|
|
object => $self, |
381
|
13
|
|
|
|
|
59
|
error => "migrated value error:\n\t" . $self->error_msg |
382
|
|
|
|
|
|
|
); |
383
|
13
|
100
|
|
|
|
53
|
} |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
# old value is always undef when this method is called |
386
|
|
|
|
|
|
|
$self->notify_change( note => 'migrated value', new => $result ) |
387
|
7
|
|
|
|
|
27
|
if length($result); # skip empty value (i.e. '') |
388
|
|
|
|
|
|
|
$self->{data} = $result; |
389
|
|
|
|
|
|
|
|
390
|
7
|
50
|
|
|
|
22
|
return $ok ? $result : undef; |
391
|
0
|
|
|
|
|
0
|
} |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
my @choice = ref $args[0] ? @{ $args[0] } : @args; |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
$logger->debug( $self->name, " setup_enum_choice with '", join( "','", @choice ), "'" ); |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
$self->{choice} = \@choice; |
398
|
7
|
50
|
|
|
|
33
|
|
399
|
|
|
|
|
|
|
# store all enum values in a hash. This way, checking |
400
|
7
|
|
|
|
|
18
|
# whether a value is present in the enum set is easier |
401
|
|
|
|
|
|
|
delete $self->{choice_hash} if defined $self->{choice_hash}; |
402
|
7
|
50
|
|
|
|
21
|
|
403
|
|
|
|
|
|
|
for ( @choice ) { $self->{choice_hash}{$_} = 1; } |
404
|
|
|
|
|
|
|
|
405
|
1091
|
|
|
1091
|
0
|
1644
|
# delete the current value if it does not fit in the new |
|
1091
|
|
|
|
|
1598
|
|
|
1091
|
|
|
|
|
1640
|
|
|
1091
|
|
|
|
|
1393
|
|
406
|
1091
|
100
|
|
|
|
2959
|
# choice |
|
878
|
|
|
|
|
2776
|
|
407
|
|
|
|
|
|
|
for ( qw/data preset/ ) { |
408
|
1091
|
|
|
|
|
3019
|
my $lv = $self->{$_}; |
409
|
|
|
|
|
|
|
if ( defined $lv and not defined $self->{choice_hash}{$lv} ) { |
410
|
1091
|
|
|
|
|
9154
|
delete $self->{$_}; |
411
|
|
|
|
|
|
|
} |
412
|
|
|
|
|
|
|
} |
413
|
|
|
|
|
|
|
return; |
414
|
1091
|
100
|
|
|
|
3297
|
} |
415
|
|
|
|
|
|
|
|
416
|
1091
|
|
|
|
|
2211
|
my ( $self, $what, $ref ) = @_; |
|
3643
|
|
|
|
|
6971
|
|
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
my $str = $self->{$what} = delete $ref->{$what}; |
419
|
|
|
|
|
|
|
return unless defined $str; |
420
|
1091
|
|
|
|
|
2311
|
my $vt = $self->{value_type}; |
421
|
2182
|
|
|
|
|
3287
|
|
422
|
2182
|
100
|
100
|
|
|
5308
|
if ( $vt ne 'uniline' and $vt ne 'string' and $vt ne 'enum') { |
423
|
6
|
|
|
|
|
20
|
Config::Model::Exception::Model->throw( |
424
|
|
|
|
|
|
|
object => $self, |
425
|
|
|
|
|
|
|
error => "Can't use $what regexp with $vt, expected 'enum', 'uniline' or 'string'" |
426
|
1091
|
|
|
|
|
2296
|
); |
427
|
|
|
|
|
|
|
} |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
$logger->debug( $self->name, " setup $what regexp with '$str'" ); |
430
|
29
|
|
|
29
|
0
|
61
|
$self->{ $what . '_regexp' } = eval { qr/$str/; }; |
431
|
|
|
|
|
|
|
|
432
|
29
|
|
|
|
|
93
|
if ($@) { |
433
|
29
|
50
|
|
|
|
66
|
Config::Model::Exception::Model->throw( |
434
|
29
|
|
|
|
|
57
|
object => $self, |
435
|
|
|
|
|
|
|
error => "Unvalid $what regexp for '$str': $@" |
436
|
29
|
50
|
66
|
|
|
129
|
); |
|
|
|
33
|
|
|
|
|
437
|
0
|
|
|
|
|
0
|
} |
438
|
|
|
|
|
|
|
return; |
439
|
|
|
|
|
|
|
} |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
my ( $self, $what, $ref ) = @_; |
442
|
|
|
|
|
|
|
|
443
|
29
|
|
|
|
|
84
|
my $regexp_info = delete $ref->{$what}; |
444
|
29
|
|
|
|
|
241
|
return unless defined $regexp_info; |
|
29
|
|
|
|
|
245
|
|
445
|
|
|
|
|
|
|
|
446
|
29
|
50
|
|
|
|
77
|
$self->{$what} = $regexp_info; |
447
|
0
|
|
|
|
|
0
|
|
448
|
|
|
|
|
|
|
my $vt = $self->{value_type}; |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
if ( $vt ne 'uniline' and $vt ne 'string' and $vt ne 'enum') { |
451
|
|
|
|
|
|
|
Config::Model::Exception::Model->throw( |
452
|
29
|
|
|
|
|
43
|
object => $self, |
453
|
|
|
|
|
|
|
error => "Can't use $what regexp with $vt, expected 'enum', 'uniline' or 'string'" |
454
|
|
|
|
|
|
|
); |
455
|
|
|
|
|
|
|
} |
456
|
26
|
|
|
26
|
0
|
49
|
|
457
|
|
|
|
|
|
|
if ( not ref $regexp_info and $what ne 'warn' ) { |
458
|
26
|
|
|
|
|
49
|
warn $self->name, ": deprecated $what style. Use a hash ref\n"; |
459
|
26
|
50
|
|
|
|
58
|
} |
460
|
|
|
|
|
|
|
|
461
|
26
|
|
|
|
|
46
|
my $h = ref $regexp_info ? $regexp_info : { $regexp_info => '' }; |
462
|
|
|
|
|
|
|
|
463
|
26
|
|
|
|
|
43
|
# just check the regexp. values are checked later in &check_value |
464
|
|
|
|
|
|
|
foreach my $regexp ( keys %$h ) { |
465
|
26
|
50
|
66
|
|
|
89
|
$logger->debug( $self->name, " hash $what regexp with '$regexp'" ); |
|
|
|
33
|
|
|
|
|
466
|
0
|
|
|
|
|
0
|
eval { qr/$regexp/; }; |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
if ($@) { |
469
|
|
|
|
|
|
|
Config::Model::Exception::Model->throw( |
470
|
|
|
|
|
|
|
object => $self, |
471
|
|
|
|
|
|
|
error => "Unvalid $what regexp '$regexp': $@" |
472
|
26
|
50
|
33
|
|
|
68
|
); |
473
|
0
|
|
|
|
|
0
|
} |
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
my $v = $h->{$regexp}; |
476
|
26
|
50
|
|
|
|
55
|
Config::Model::Exception::Model->throw( |
477
|
|
|
|
|
|
|
object => $self, |
478
|
|
|
|
|
|
|
error => "value of $what regexp '$regexp' is not a hash ref but '$v'" |
479
|
26
|
|
|
|
|
65
|
) unless ref $v eq 'HASH'; |
480
|
29
|
|
|
|
|
59
|
|
481
|
29
|
|
|
|
|
296
|
} |
|
29
|
|
|
|
|
301
|
|
482
|
|
|
|
|
|
|
return; |
483
|
29
|
50
|
|
|
|
109
|
} |
484
|
0
|
|
|
|
|
0
|
|
485
|
|
|
|
|
|
|
my ( $self, $ref ) = @_; |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
my $str = $self->{grammar} = delete $ref->{grammar}; |
488
|
|
|
|
|
|
|
return unless defined $str; |
489
|
|
|
|
|
|
|
my $vt = $self->{value_type}; |
490
|
29
|
|
|
|
|
48
|
|
491
|
29
|
50
|
|
|
|
107
|
if ( $vt ne 'uniline' and $vt ne 'string' ) { |
492
|
|
|
|
|
|
|
Config::Model::Exception::Model->throw( |
493
|
|
|
|
|
|
|
object => $self, |
494
|
|
|
|
|
|
|
error => "Can't use match regexp with $vt, " . "expected 'uniline' or 'string'" |
495
|
|
|
|
|
|
|
); |
496
|
|
|
|
|
|
|
} |
497
|
26
|
|
|
|
|
51
|
|
498
|
|
|
|
|
|
|
my @lines = split /\n/, $str; |
499
|
|
|
|
|
|
|
chomp @lines; |
500
|
|
|
|
|
|
|
if ( $lines[0] !~ /^check:/ ) { |
501
|
1
|
|
|
1
|
0
|
3
|
$lines[0] = 'check: ' . $lines[0] . ' /\s*\Z/ '; |
502
|
|
|
|
|
|
|
} |
503
|
1
|
|
|
|
|
4
|
|
504
|
1
|
50
|
|
|
|
3
|
my $actual_grammar = join( "\n", @lines ) . "\n"; |
505
|
1
|
|
|
|
|
3
|
$logger->debug( $self->name, " setup_grammar_check with '$actual_grammar'" ); |
506
|
|
|
|
|
|
|
eval { $self->{validation_parser} = Parse::RecDescent->new($actual_grammar); }; |
507
|
1
|
50
|
33
|
|
|
7
|
|
508
|
0
|
|
|
|
|
0
|
if ($@) { |
509
|
|
|
|
|
|
|
Config::Model::Exception::Model->throw( |
510
|
|
|
|
|
|
|
object => $self, |
511
|
|
|
|
|
|
|
error => "Unvalid grammar for '$str': $@" |
512
|
|
|
|
|
|
|
); |
513
|
|
|
|
|
|
|
} |
514
|
1
|
|
|
|
|
7
|
return; |
515
|
1
|
|
|
|
|
3
|
} |
516
|
1
|
50
|
|
|
|
6
|
|
517
|
0
|
|
|
|
|
0
|
# warning : call to 'set' are not cumulative. Default value are always |
518
|
|
|
|
|
|
|
# restored. Lest keeping track of what was modified with 'set' is |
519
|
|
|
|
|
|
|
# too confusing. |
520
|
1
|
|
|
|
|
5
|
# cleanup all parameters that are handled by warp |
521
|
1
|
|
|
|
|
72
|
for ( @allowed_warp_params ) { delete $self->{$_} } |
522
|
1
|
|
|
|
|
8
|
|
|
1
|
|
|
|
|
10
|
|
523
|
|
|
|
|
|
|
# merge data passed to the constructor with data passed to set_properties |
524
|
1
|
50
|
|
|
|
13721
|
my %args = ( %{ $self->backup // {} }, @args ); |
525
|
0
|
|
|
|
|
0
|
|
526
|
|
|
|
|
|
|
# these are handled by Node or Warper |
527
|
|
|
|
|
|
|
for ( qw/level/ ) { delete $args{$_} } |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
if ( $logger->is_trace ) { |
530
|
1
|
|
|
|
|
6
|
$logger->trace( "Leaf '" . $self->name . "' set_properties called with '", |
531
|
|
|
|
|
|
|
join( "','", sort keys %args ), "'" ); |
532
|
|
|
|
|
|
|
} |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
if ( defined $args{value_type} |
535
|
|
|
|
|
|
|
and $args{value_type} eq 'reference' |
536
|
3975
|
|
|
3975
|
0
|
5744
|
and not defined $self->{refer_to} |
|
3975
|
|
|
|
|
5091
|
|
|
3975
|
|
|
|
|
5234
|
|
|
3975
|
|
|
|
|
4713
|
|
537
|
|
|
|
|
|
|
and not defined $self->{computed_refer_to} ) { |
538
|
3975
|
|
|
|
|
8353
|
Config::Model::Exception::Model->throw( |
|
75525
|
|
|
|
|
89876
|
|
539
|
|
|
|
|
|
|
object => $self, |
540
|
|
|
|
|
|
|
error => "Missing 'refer_to' or 'computed_refer_to' " |
541
|
3975
|
|
100
|
|
|
5475
|
. "parameter with 'reference' value_type " |
|
3975
|
|
|
|
|
18527
|
|
542
|
|
|
|
|
|
|
); |
543
|
|
|
|
|
|
|
} |
544
|
3975
|
|
|
|
|
8455
|
|
|
3975
|
|
|
|
|
6965
|
|
545
|
|
|
|
|
|
|
for (qw/min max mandatory warn replace_follow assert warn_if warn_unless |
546
|
3975
|
100
|
|
|
|
11064
|
write_as/) { |
547
|
134
|
|
|
|
|
586
|
$self->{$_} = delete $args{$_} if defined $args{$_}; |
548
|
|
|
|
|
|
|
} |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
if ($args{replace}) { |
551
|
3975
|
0
|
33
|
|
|
28955
|
$self->{replace} = delete $args{replace}; |
|
|
|
33
|
|
|
|
|
|
|
|
0
|
|
|
|
|
552
|
|
|
|
|
|
|
my $old = $self->_fetch_no_check; |
553
|
|
|
|
|
|
|
if (defined $old) { |
554
|
|
|
|
|
|
|
my $new = $self->apply_replace($old); |
555
|
0
|
|
|
|
|
0
|
$self->_store_value($new); |
556
|
|
|
|
|
|
|
} |
557
|
|
|
|
|
|
|
} |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
$self->set_help( \%args ); |
560
|
|
|
|
|
|
|
$self->set_value_type( \%args ); |
561
|
|
|
|
|
|
|
$self->set_default( \%args ); |
562
|
3975
|
|
|
|
|
6905
|
$self->set_convert( \%args ) if defined $args{convert}; |
563
|
|
|
|
|
|
|
$self->setup_match_regexp( match => \%args ) if defined $args{match}; |
564
|
35775
|
100
|
|
|
|
54740
|
foreach (qw/warn_if_match warn_unless_match/) { |
565
|
|
|
|
|
|
|
$self->check_validation_regexp( $_ => \%args ) if defined $args{$_}; |
566
|
|
|
|
|
|
|
} |
567
|
3975
|
100
|
|
|
|
8730
|
$self->setup_grammar_check( \%args ) if defined $args{grammar}; |
568
|
6
|
|
|
|
|
18
|
|
569
|
6
|
|
|
|
|
25
|
# cannot be warped |
570
|
6
|
100
|
|
|
|
23
|
$self->set_migrate_from( \%args ) if defined $args{migrate_from}; |
571
|
3
|
|
|
|
|
13
|
|
572
|
3
|
|
|
|
|
11
|
Config::Model::Exception::Model->throw( |
573
|
|
|
|
|
|
|
object => $self, |
574
|
|
|
|
|
|
|
error => "write_as is allowed only with boolean values" |
575
|
|
|
|
|
|
|
) if defined $self->{write_as} and $self->{value_type} ne 'boolean'; |
576
|
3975
|
|
|
|
|
10977
|
|
577
|
3975
|
|
|
|
|
11020
|
Config::Model::Exception::Model->throw( |
578
|
3974
|
|
|
|
|
11182
|
object => $self, |
579
|
3972
|
100
|
|
|
|
8340
|
error => "Unexpected parameters: " . join( ' ', each %args ) ) if scalar keys %args; |
580
|
3972
|
100
|
|
|
|
7849
|
|
581
|
3972
|
|
|
|
|
7972
|
if ( $self->has_warped_slaves ) { |
582
|
7944
|
100
|
|
|
|
14849
|
my $value = $self->_fetch_no_check; |
583
|
|
|
|
|
|
|
$self->trigger_warp($value); |
584
|
3972
|
100
|
|
|
|
7672
|
} |
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
# when properties are changed, a check is required to validate new constraints |
587
|
3972
|
100
|
|
|
|
7531
|
$self->needs_check(1); |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
return $self; |
590
|
|
|
|
|
|
|
} |
591
|
|
|
|
|
|
|
|
592
|
3972
|
50
|
66
|
|
|
8937
|
# simple but may be overridden |
593
|
|
|
|
|
|
|
my ( $self, $args ) = @_; |
594
|
3972
|
50
|
|
|
|
8493
|
return unless defined $args->{help}; |
595
|
|
|
|
|
|
|
$self->{help} = delete $args->{help}; |
596
|
|
|
|
|
|
|
return; |
597
|
|
|
|
|
|
|
} |
598
|
3972
|
100
|
|
|
|
10798
|
|
599
|
17
|
|
|
|
|
168
|
# this code is somewhat dead as warping value_type is no longer supported |
600
|
17
|
|
|
|
|
75
|
# but it may come back. |
601
|
|
|
|
|
|
|
my ( $self, $arg_ref ) = @_; |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
my $value_type = delete $arg_ref->{value_type} || $self->value_type; |
604
|
3972
|
|
|
|
|
33374
|
|
605
|
|
|
|
|
|
|
Config::Model::Exception::Model->throw( |
606
|
3972
|
|
|
|
|
89022
|
object => $self, |
607
|
|
|
|
|
|
|
error => "Value set: undefined value_type" |
608
|
|
|
|
|
|
|
) unless defined $value_type; |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
$self->{value_type} = $value_type; |
611
|
3975
|
|
|
3975
|
0
|
6715
|
|
612
|
3975
|
100
|
|
|
|
9165
|
if ( $value_type eq 'boolean' ) { |
613
|
240
|
|
|
|
|
557
|
|
614
|
240
|
|
|
|
|
449
|
# convert any value to boolean |
615
|
|
|
|
|
|
|
$self->{data} = $self->{data} ? 1 : 0 if defined $self->{data}; |
616
|
|
|
|
|
|
|
$self->{preset} = $self->{preset} ? 1 : 0 if defined $self->{preset}; |
617
|
|
|
|
|
|
|
$self->{layered} = $self->{layered} ? 1 : 0 if defined $self->{layered}; |
618
|
|
|
|
|
|
|
} |
619
|
|
|
|
|
|
|
elsif ($value_type eq 'reference' |
620
|
3975
|
|
|
3975
|
0
|
6550
|
or $value_type eq 'enum' ) { |
621
|
|
|
|
|
|
|
my $choice = delete $arg_ref->{choice}; |
622
|
3975
|
|
66
|
|
|
16141
|
$self->setup_enum_choice($choice) if defined $choice; |
623
|
|
|
|
|
|
|
} |
624
|
3975
|
100
|
|
|
|
8855
|
elsif (any {$value_type eq $_} qw/string integer number uniline file dir/ ) { |
625
|
|
|
|
|
|
|
Config::Model::Exception::Model->throw( |
626
|
|
|
|
|
|
|
object => $self, |
627
|
|
|
|
|
|
|
error => "'choice' parameter forbidden with type " . $value_type |
628
|
|
|
|
|
|
|
) if defined $arg_ref->{choice}; |
629
|
3974
|
|
|
|
|
5966
|
} |
630
|
|
|
|
|
|
|
else { |
631
|
3974
|
100
|
100
|
|
|
26684
|
my $msg = |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
632
|
|
|
|
|
|
|
"Unexpected value type : '$value_type' " |
633
|
|
|
|
|
|
|
. "expected 'boolean', 'enum', 'uniline', 'string' or 'integer'." |
634
|
628
|
0
|
|
|
|
1332
|
. "Value type can also be set up with a warp relation"; |
|
|
50
|
|
|
|
|
|
635
|
628
|
0
|
|
|
|
1211
|
Config::Model::Exception::Model->throw( object => $self, error => $msg ) |
|
|
50
|
|
|
|
|
|
636
|
628
|
0
|
|
|
|
1596
|
unless defined $self->{warp}; |
|
|
50
|
|
|
|
|
|
637
|
|
|
|
|
|
|
} |
638
|
|
|
|
|
|
|
return; |
639
|
|
|
|
|
|
|
} |
640
|
965
|
|
|
|
|
1871
|
|
641
|
965
|
100
|
|
|
|
3696
|
|
642
|
|
|
|
|
|
|
my $self = shift; |
643
|
4910
|
|
|
4910
|
|
8743
|
|
644
|
|
|
|
|
|
|
if ( defined $self->{refer_to} ) { |
645
|
|
|
|
|
|
|
$self->{ref_object} = Config::Model::IdElementReference->new( |
646
|
|
|
|
|
|
|
refer_to => $self->{refer_to}, |
647
|
2381
|
50
|
|
|
|
5654
|
config_elt => $self, |
648
|
|
|
|
|
|
|
); |
649
|
|
|
|
|
|
|
} |
650
|
0
|
|
|
|
|
0
|
elsif ( defined $self->{computed_refer_to} ) { |
651
|
|
|
|
|
|
|
$self->{ref_object} = Config::Model::IdElementReference->new( |
652
|
|
|
|
|
|
|
computed_refer_to => $self->{computed_refer_to}, |
653
|
|
|
|
|
|
|
config_elt => $self, |
654
|
|
|
|
|
|
|
); |
655
|
0
|
0
|
|
|
|
0
|
|
656
|
|
|
|
|
|
|
# refer_to registration is done for all element that are used as |
657
|
3974
|
|
|
|
|
10348
|
# variable for complex reference (ie '- $foo' , {foo => '- bar'} ) |
658
|
|
|
|
|
|
|
$self->register_in_other_value( $self->{computed_refer_to}{variables} ); |
659
|
|
|
|
|
|
|
} |
660
|
|
|
|
|
|
|
else { |
661
|
|
|
|
|
|
|
croak "value's submit_to_refer_to: undefined refer_to or computed_refer_to"; |
662
|
55
|
|
|
55
|
0
|
105
|
} |
663
|
|
|
|
|
|
|
return; |
664
|
55
|
100
|
|
|
|
180
|
} |
|
|
50
|
|
|
|
|
|
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
return $self->setup_enum_choice(@args); |
667
|
51
|
|
|
|
|
845
|
} |
668
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
my $self = shift; |
670
|
|
|
|
|
|
|
return $self->{ref_object}; |
671
|
|
|
|
|
|
|
} |
672
|
|
|
|
|
|
|
|
673
|
4
|
|
|
|
|
61
|
carp "warning: built_in sub is deprecated, use upstream_default"; |
674
|
|
|
|
|
|
|
goto &upstream_default; |
675
|
|
|
|
|
|
|
} |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
## FIXME::what about id ?? |
678
|
4
|
|
|
|
|
23
|
my $self = shift; |
679
|
|
|
|
|
|
|
my $name = $self->{parent}->name . ' ' . $self->{element_name}; |
680
|
|
|
|
|
|
|
$name .= ':' . $self->{index_value} if defined $self->{index_value}; |
681
|
0
|
|
|
|
|
0
|
return $name; |
682
|
|
|
|
|
|
|
} |
683
|
55
|
|
|
|
|
168
|
|
684
|
|
|
|
|
|
|
return 'leaf'; |
685
|
|
|
|
|
|
|
} |
686
|
213
|
|
|
213
|
0
|
356
|
|
|
213
|
|
|
|
|
303
|
|
|
213
|
|
|
|
|
328
|
|
|
213
|
|
|
|
|
261
|
|
687
|
213
|
|
|
|
|
616
|
return 'leaf'; |
688
|
|
|
|
|
|
|
} |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
my $self = shift; |
691
|
0
|
|
|
0
|
0
|
0
|
|
692
|
0
|
|
|
|
|
0
|
if ( not defined $self->compute ) { |
693
|
|
|
|
|
|
|
return 1; |
694
|
|
|
|
|
|
|
} |
695
|
|
|
|
|
|
|
if ( $self->compute_obj->allow_user_override ) { |
696
|
0
|
|
|
0
|
0
|
0
|
return 1; |
697
|
0
|
|
|
|
|
0
|
} |
698
|
|
|
|
|
|
|
return; |
699
|
|
|
|
|
|
|
} |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
my $self = shift; |
702
|
10469
|
|
|
10469
|
1
|
14525
|
return @{ $self->{backup}{choice} || [] }; |
703
|
10469
|
|
|
|
|
24013
|
} |
704
|
10469
|
100
|
|
|
|
22505
|
|
705
|
10469
|
|
|
|
|
40600
|
my $self = shift; |
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
# just in case the reference_object has been changed |
708
|
|
|
|
|
|
|
if ( defined $self->{refer_to} or defined $self->{computed_refer_to} ) { |
709
|
7137
|
|
|
7137
|
1
|
13166
|
$self->{ref_object}->get_choice_from_referred_to; |
710
|
|
|
|
|
|
|
} |
711
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
return @{ $self->{choice} || [] }; |
713
|
6442
|
|
|
6442
|
0
|
9952
|
} |
714
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
my $self = shift; |
716
|
|
|
|
|
|
|
|
717
|
0
|
|
|
0
|
1
|
0
|
my $type = $self->value_type; |
718
|
|
|
|
|
|
|
my @choice = $type eq 'enum' ? $self->get_choice : (); |
719
|
0
|
0
|
|
|
|
0
|
my $choice_str = @choice ? ' (' . join( ',', @choice ) . ')' : ''; |
720
|
0
|
|
|
|
|
0
|
|
721
|
|
|
|
|
|
|
my @items = ( 'type: ' . $self->value_type . $choice_str, ); |
722
|
0
|
0
|
|
|
|
0
|
|
723
|
0
|
|
|
|
|
0
|
my $std = $self->fetch(qw/mode standard check no/); |
724
|
|
|
|
|
|
|
|
725
|
0
|
|
|
|
|
0
|
if ( defined $self->upstream_default ) { |
726
|
|
|
|
|
|
|
push @items, "upstream_default value: " . $self->map_write_as( $self->upstream_default ); |
727
|
|
|
|
|
|
|
} |
728
|
|
|
|
|
|
|
elsif ( defined $std ) { |
729
|
215
|
|
|
215
|
0
|
342
|
push @items, "default value: $std"; |
730
|
215
|
100
|
|
|
|
305
|
} |
|
215
|
|
|
|
|
1208
|
|
731
|
|
|
|
|
|
|
elsif ( defined $self->refer_to ) { |
732
|
|
|
|
|
|
|
push @items, "reference to: " . $self->refer_to; |
733
|
|
|
|
|
|
|
} |
734
|
15
|
|
|
15
|
1
|
55
|
elsif ( defined $self->computed_refer_to ) { |
735
|
|
|
|
|
|
|
push @items, "computed reference to: " . $self->computed_refer_to; |
736
|
|
|
|
|
|
|
} |
737
|
15
|
100
|
66
|
|
|
88
|
|
738
|
8
|
|
|
|
|
31
|
my $m = $self->mandatory; |
739
|
|
|
|
|
|
|
push @items, "is mandatory: " . ( $m ? 'yes' : 'no' ) if defined $m; |
740
|
|
|
|
|
|
|
|
741
|
15
|
50
|
|
|
|
32
|
foreach my $what (qw/min max warn grammar/) { |
|
15
|
|
|
|
|
96
|
|
742
|
|
|
|
|
|
|
my $v = $self->$what(); |
743
|
|
|
|
|
|
|
push @items, "$what value: $v" if defined $v; |
744
|
|
|
|
|
|
|
} |
745
|
4
|
|
|
4
|
1
|
7
|
|
746
|
|
|
|
|
|
|
foreach my $what (qw/warn_if_match warn_unless_match/) { |
747
|
4
|
|
|
|
|
11
|
my $v = $self->$what(); |
748
|
4
|
100
|
|
|
|
13
|
foreach my $k ( keys %$v ) { |
749
|
4
|
100
|
|
|
|
12
|
push @items, "$what value: $k"; |
750
|
|
|
|
|
|
|
} |
751
|
4
|
|
|
|
|
20
|
} |
752
|
|
|
|
|
|
|
|
753
|
4
|
|
|
|
|
12
|
foreach my $what (qw/write_as/) { |
754
|
|
|
|
|
|
|
my $v = $self->$what(); |
755
|
4
|
100
|
|
|
|
40
|
push @items, "$what: @$v" if defined $v; |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
756
|
1
|
|
|
|
|
5
|
} |
757
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
return @items ; |
759
|
0
|
|
|
|
|
0
|
} |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
my $self = shift; |
762
|
1
|
|
|
|
|
5
|
|
763
|
|
|
|
|
|
|
my $help = $self->{help}; |
764
|
|
|
|
|
|
|
|
765
|
0
|
|
|
|
|
0
|
return $help unless @_; |
766
|
|
|
|
|
|
|
|
767
|
|
|
|
|
|
|
my $on_value = shift; |
768
|
4
|
|
|
|
|
10
|
return unless defined $on_value; |
769
|
4
|
0
|
|
|
|
15
|
|
|
|
50
|
|
|
|
|
|
770
|
|
|
|
|
|
|
my $fallback = $help->{'.'} || $help -> {'.*'}; |
771
|
4
|
|
|
|
|
6
|
foreach my $k (sort { length($b) cmp length($a) } keys %$help) { |
772
|
16
|
|
|
|
|
28
|
next if $k eq '' or $k eq '.*'; |
773
|
16
|
50
|
|
|
|
32
|
return $help->{$k} if $on_value =~ /^$k/; |
774
|
|
|
|
|
|
|
} |
775
|
|
|
|
|
|
|
return $fallback; |
776
|
4
|
|
|
|
|
5
|
} |
777
|
8
|
|
|
|
|
18
|
|
778
|
8
|
|
|
|
|
21
|
# construct an error message for enum types |
779
|
0
|
|
|
|
|
0
|
my ( $self, $value ) = @_; |
780
|
|
|
|
|
|
|
my @error; |
781
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
if ( not defined $self->{choice} ) { |
783
|
4
|
|
|
|
|
9
|
push @error, "$self->{value_type} type has no defined choice", $self->warp_error; |
784
|
4
|
|
|
|
|
9
|
return @error; |
785
|
4
|
100
|
|
|
|
10
|
} |
786
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
my @choice = map { "'$_'" } $self->get_choice; |
788
|
4
|
|
|
|
|
14
|
my $var = $self->{value_type}; |
789
|
|
|
|
|
|
|
my $str_value = defined $value ? $value : '<undef>'; |
790
|
|
|
|
|
|
|
push @error, |
791
|
|
|
|
|
|
|
"$self->{value_type} type does not know '$value'. Expected " . join( " or ", @choice ); |
792
|
52
|
|
|
52
|
1
|
6099
|
push @error, |
793
|
|
|
|
|
|
|
"Expected list is given by '" . join( "', '", @{ $self->{referred_to_path} } ) . "'" |
794
|
52
|
|
|
|
|
92
|
if $var eq 'reference' && defined $self->{referred_to_path}; |
795
|
|
|
|
|
|
|
push @error, $self->warp_error if $self->{warp}; |
796
|
52
|
100
|
|
|
|
109
|
|
797
|
|
|
|
|
|
|
return @error; |
798
|
51
|
|
|
|
|
89
|
} |
799
|
51
|
50
|
|
|
|
84
|
|
800
|
|
|
|
|
|
|
my $value = $args{value}; |
801
|
51
|
|
66
|
|
|
149
|
my $quiet = $args{quiet} || 0; |
802
|
51
|
|
|
|
|
171
|
my $check = $args{check} || 'yes'; |
|
27
|
|
|
|
|
58
|
|
803
|
25
|
50
|
33
|
|
|
102
|
my $apply_fix = $args{fix} || 0; |
804
|
25
|
100
|
|
|
|
377
|
my $mode = $args{mode} || 'backend'; |
805
|
|
|
|
|
|
|
|
806
|
39
|
|
|
|
|
230
|
#croak "Cannot specify a value with fix = 1" if $apply_fix and exists $args{value} ; |
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
if ( $logger->is_debug ) { |
809
|
|
|
|
|
|
|
my $v = defined $value ? $value : '<undef>'; |
810
|
|
|
|
|
|
|
my $loc = $self->location; |
811
|
9
|
|
|
9
|
0
|
30
|
my $msg = |
812
|
9
|
|
|
|
|
19
|
"called from " |
813
|
|
|
|
|
|
|
. join( ' ', caller ) |
814
|
9
|
50
|
|
|
|
33
|
. " with value '$v' mode $mode check $check on '$loc'"; |
815
|
0
|
|
|
|
|
0
|
$logger->debug($msg); |
816
|
0
|
|
|
|
|
0
|
} |
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
# need to keep track to update GUI |
819
|
9
|
|
|
|
|
36
|
$self->{nb_of_fixes} = 0; # reset before check |
|
18
|
|
|
|
|
56
|
|
820
|
9
|
|
|
|
|
22
|
|
821
|
9
|
50
|
|
|
|
30
|
my @error; |
822
|
9
|
|
|
|
|
47
|
my @warn; |
823
|
|
|
|
|
|
|
my $vt = $self->value_type ; |
824
|
|
|
|
|
|
|
|
825
|
0
|
|
|
|
|
0
|
if ( not defined $value ) { |
826
|
9
|
50
|
66
|
|
|
51
|
|
827
|
9
|
50
|
|
|
|
27
|
# accept with no other check |
828
|
|
|
|
|
|
|
} |
829
|
9
|
|
|
|
|
30
|
elsif ( not defined $vt ) { |
830
|
|
|
|
|
|
|
push @error, "Undefined value_type"; |
831
|
|
|
|
|
|
|
} |
832
|
4513
|
|
|
4513
|
|
5723
|
elsif (( $vt =~ /integer/ and $value =~ /^-?\d+$/ ) |
|
4513
|
|
|
|
|
5694
|
|
|
4513
|
|
|
|
|
8300
|
|
|
4513
|
|
|
|
|
5436
|
|
833
|
4513
|
|
|
|
|
7263
|
or ( $vt =~ /number/ and $value =~ /^-?\d+(\.\d+)?$/ ) ) { |
834
|
4513
|
|
50
|
|
|
13877
|
|
835
|
4513
|
|
100
|
|
|
11465
|
# correct number or integer. check min max |
836
|
4513
|
|
100
|
|
|
11658
|
push @error, "value $value > max limit $self->{max}" |
837
|
4513
|
|
100
|
|
|
12801
|
if defined $self->{max} and $value > $self->{max}; |
838
|
|
|
|
|
|
|
push @error, "value $value < min limit $self->{min}" |
839
|
|
|
|
|
|
|
if defined $self->{min} and $value < $self->{min}; |
840
|
|
|
|
|
|
|
} |
841
|
4513
|
100
|
|
|
|
10253
|
elsif ( $vt =~ /integer/ and $value =~ /^-?\d+(\.\d+)?$/ ) { |
842
|
161
|
100
|
|
|
|
654
|
push @error, "Type $vt: value $value is a number " . "but not an integer"; |
843
|
161
|
|
|
|
|
470
|
} |
844
|
161
|
|
|
|
|
586
|
elsif ( $vt eq 'file' or $vt eq 'dir' ) { |
845
|
|
|
|
|
|
|
if (defined $value) { |
846
|
|
|
|
|
|
|
my $path = path($value); |
847
|
|
|
|
|
|
|
if ($path->exists) { |
848
|
161
|
|
|
|
|
2626
|
my $check_sub = 'is_'.$vt ; |
849
|
|
|
|
|
|
|
push @warn, "$value is not a $vt" if not path($value)->$check_sub; |
850
|
|
|
|
|
|
|
} |
851
|
|
|
|
|
|
|
else { |
852
|
4513
|
|
|
|
|
26401
|
push @warn, "$vt $value does not exists" ; |
853
|
|
|
|
|
|
|
} |
854
|
4513
|
|
|
|
|
7056
|
} |
855
|
|
|
|
|
|
|
} |
856
|
4513
|
|
|
|
|
10370
|
elsif ( $vt eq 'reference' ) { |
857
|
|
|
|
|
|
|
|
858
|
4513
|
100
|
100
|
|
|
44869
|
# just in case the reference_object has been changed |
|
|
50
|
66
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
859
|
|
|
|
|
|
|
if ( defined $self->{refer_to} or defined $self->{computed_refer_to} ) { |
860
|
|
|
|
|
|
|
$self->{ref_object}->get_choice_from_referred_to; |
861
|
|
|
|
|
|
|
} |
862
|
|
|
|
|
|
|
|
863
|
0
|
|
|
|
|
0
|
if ( length($value) |
864
|
|
|
|
|
|
|
and defined $self->{choice_hash} |
865
|
|
|
|
|
|
|
and not defined $self->{choice_hash}{$value} ) { |
866
|
|
|
|
|
|
|
push @error, ( $quiet ? 'reference error' : $self->enum_error($value) ); |
867
|
|
|
|
|
|
|
} |
868
|
|
|
|
|
|
|
} |
869
|
|
|
|
|
|
|
elsif ( $vt eq 'enum' ) { |
870
|
347
|
100
|
100
|
|
|
1539
|
if ( length($value) |
871
|
|
|
|
|
|
|
and defined $self->{choice_hash} |
872
|
347
|
50
|
66
|
|
|
1188
|
and not defined $self->{choice_hash}{$value} ) { |
873
|
|
|
|
|
|
|
push @error, ( $quiet ? 'enum error' : $self->enum_error($value) ); |
874
|
|
|
|
|
|
|
} |
875
|
1
|
|
|
|
|
7
|
} |
876
|
|
|
|
|
|
|
elsif ( $vt eq 'boolean' ) { |
877
|
|
|
|
|
|
|
push @error, "error: '$value' is not boolean, i.e. not " |
878
|
5
|
50
|
|
|
|
10
|
. join ( ' or ', map { "'$_'"} $self->map_write_as(qw/0 1/)) |
879
|
5
|
|
|
|
|
12
|
unless $value =~ /^[01]$/; |
880
|
5
|
100
|
|
|
|
126
|
} |
881
|
4
|
|
|
|
|
73
|
elsif ($vt =~ /integer/ |
882
|
4
|
100
|
|
|
|
12
|
or $vt =~ /number/ ) { |
883
|
|
|
|
|
|
|
push @error, "Value '$value' is not of type " . $vt; |
884
|
|
|
|
|
|
|
} |
885
|
1
|
|
|
|
|
30
|
elsif ( $vt eq 'uniline' ) { |
886
|
|
|
|
|
|
|
push @error, '"uniline" value must not contain embedded newlines (\n)' |
887
|
|
|
|
|
|
|
if $value =~ /\n/; |
888
|
|
|
|
|
|
|
} |
889
|
|
|
|
|
|
|
elsif ( $vt eq 'string' ) { |
890
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
# accepted, no more check |
892
|
108
|
50
|
66
|
|
|
484
|
} |
893
|
108
|
|
|
|
|
429
|
else { |
894
|
|
|
|
|
|
|
my $choice_msg = ''; |
895
|
|
|
|
|
|
|
$choice_msg .= ", choice " . join( " ", $self->get_choice ) . ")" |
896
|
108
|
100
|
66
|
|
|
801
|
if defined $self->{choice}; |
|
|
|
100
|
|
|
|
|
897
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
my $msg = |
899
|
5
|
50
|
|
|
|
36
|
"Cannot check value_type '$vt' (value '$value'$choice_msg)"; |
900
|
|
|
|
|
|
|
Config::Model::Exception::Model->throw( object => $self, message => $msg ); |
901
|
|
|
|
|
|
|
} |
902
|
|
|
|
|
|
|
|
903
|
758
|
100
|
66
|
|
|
5304
|
if ( defined $self->{match_regexp} and defined $value ) { |
|
|
|
100
|
|
|
|
|
904
|
|
|
|
|
|
|
push @error, "value '$value' does not match regexp " . $self->{match} |
905
|
|
|
|
|
|
|
unless $value =~ $self->{match_regexp}; |
906
|
4
|
50
|
|
|
|
23
|
} |
907
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
if ( $mode ne 'custom' ) { |
909
|
|
|
|
|
|
|
if ( $self->{warn_if_match} ) { |
910
|
|
|
|
|
|
|
my $test_sub = sub { |
911
|
250
|
100
|
|
|
|
1092
|
my $v = shift // ''; |
|
8
|
|
|
|
|
32
|
|
912
|
|
|
|
|
|
|
my $r = shift; |
913
|
|
|
|
|
|
|
$v =~ /$r/ ? 0 : 1; |
914
|
|
|
|
|
|
|
}; |
915
|
|
|
|
|
|
|
$self->run_regexp_set_on_value( \$value, $apply_fix, \@warn, 'not ', $test_sub, |
916
|
1
|
|
|
|
|
7
|
$self->{warn_if_match} ); |
917
|
|
|
|
|
|
|
} |
918
|
|
|
|
|
|
|
|
919
|
689
|
100
|
|
|
|
1982
|
if ( $self->{warn_unless_match} ) { |
920
|
|
|
|
|
|
|
my $test_sub = sub { |
921
|
|
|
|
|
|
|
my $v = shift // ''; |
922
|
|
|
|
|
|
|
my $r = shift; |
923
|
|
|
|
|
|
|
$v =~ /$r/ ? 1 : 0; |
924
|
|
|
|
|
|
|
}; |
925
|
|
|
|
|
|
|
$self->run_regexp_set_on_value( \$value, $apply_fix, \@warn, '', $test_sub, |
926
|
|
|
|
|
|
|
$self->{warn_unless_match} ); |
927
|
0
|
|
|
|
|
0
|
} |
928
|
|
|
|
|
|
|
|
929
|
0
|
0
|
|
|
|
0
|
$self->run_code_set_on_value( \$value, $apply_fix, \@error, $self->{assert} ) |
930
|
|
|
|
|
|
|
if $self->{assert}; |
931
|
0
|
|
|
|
|
0
|
$self->run_code_set_on_value( \$value, $apply_fix, \@warn, $self->{warn_unless} ) |
932
|
|
|
|
|
|
|
if $self->{warn_unless}; |
933
|
0
|
|
|
|
|
0
|
$self->run_code_set_on_value( \$value, $apply_fix, \@warn, $self->{warn_if}, 1 ) |
934
|
|
|
|
|
|
|
if $self->{warn_if}; |
935
|
|
|
|
|
|
|
} |
936
|
4513
|
100
|
100
|
|
|
11468
|
|
937
|
|
|
|
|
|
|
# unconditional warn |
938
|
45
|
100
|
|
|
|
329
|
push @warn, $self->{warn} if defined $value and $self->{warn}; |
939
|
|
|
|
|
|
|
|
940
|
|
|
|
|
|
|
if ( defined $self->{validation_parser} and defined $value ) { |
941
|
4513
|
100
|
|
|
|
9140
|
my $prd = $self->{validation_parser}; |
942
|
3806
|
100
|
|
|
|
7708
|
my ( $err_msg, $warn_msg ) = ( '', '' ); |
943
|
|
|
|
|
|
|
my $prd_check = $prd->check( $value, 1, $self, \$err_msg, \$warn_msg ); |
944
|
69
|
|
50
|
69
|
|
156
|
my $prd_result = defined $prd_check ? 1 : 0; |
945
|
69
|
|
|
|
|
87
|
$logger->debug( "grammar check on $value returned ", defined $prd_check ? $prd_check : '<undef>' ); |
946
|
69
|
100
|
|
|
|
533
|
if (not $prd_result) { |
947
|
93
|
|
|
|
|
303
|
my $msg = "value '$value' does not match grammar from model"; |
948
|
|
|
|
|
|
|
$msg .= ": $err_msg" if $err_msg; |
949
|
93
|
|
|
|
|
220
|
push @error, $msg; |
950
|
|
|
|
|
|
|
} |
951
|
|
|
|
|
|
|
push @warn, $warn_msg if $warn_msg; |
952
|
3806
|
100
|
|
|
|
7715
|
} |
953
|
|
|
|
|
|
|
|
954
|
40
|
|
50
|
40
|
|
87
|
$logger->debug( |
955
|
40
|
|
|
|
|
49
|
"check_value returns ", |
956
|
40
|
100
|
|
|
|
373
|
scalar @error, |
957
|
28
|
|
|
|
|
88
|
" errors and ", scalar @warn, " warnings" |
958
|
|
|
|
|
|
|
); |
959
|
28
|
|
|
|
|
73
|
|
960
|
|
|
|
|
|
|
# return $value because it may be modified by apply_fixes |
961
|
|
|
|
|
|
|
return ($value, \@error, \@warn); |
962
|
|
|
|
|
|
|
} |
963
|
3806
|
100
|
|
|
|
7566
|
|
964
|
|
|
|
|
|
|
my $value = $args{value}; |
965
|
3806
|
100
|
|
|
|
9444
|
my $check = $args{check} || 'yes'; |
966
|
|
|
|
|
|
|
my $mode = $args{mode} || 'backend'; |
967
|
3806
|
100
|
|
|
|
7808
|
my $error = $args{error} // carp "Missing error parameter"; |
968
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
# a value may be mandatory and have a default value with layers |
970
|
|
|
|
|
|
|
if ( $self->{mandatory} |
971
|
4513
|
100
|
100
|
|
|
12680
|
and $check eq 'yes' |
972
|
|
|
|
|
|
|
and ( $mode =~ /backend|user/ ) |
973
|
4513
|
100
|
100
|
|
|
9592
|
and ( not defined $value or not length($value) ) |
974
|
5
|
|
|
|
|
8
|
and ( not defined $self->{layered} or not length($self->{layered})) |
975
|
5
|
|
|
|
|
10
|
) { |
976
|
5
|
|
|
|
|
36
|
# check only "empty" mode. |
977
|
5
|
100
|
|
|
|
3845
|
my $msg = "Undefined mandatory value."; |
978
|
5
|
100
|
|
|
|
26
|
$msg .= $self->warp_error |
979
|
5
|
100
|
|
|
|
38
|
if defined $self->{warped_attribute}{default}; |
980
|
2
|
|
|
|
|
6
|
push $error->@*, $msg; |
981
|
2
|
50
|
|
|
|
3
|
} |
982
|
2
|
|
|
|
|
6
|
|
983
|
|
|
|
|
|
|
return; |
984
|
5
|
50
|
|
|
|
11
|
} |
985
|
|
|
|
|
|
|
|
986
|
|
|
|
|
|
|
my ($value, $error, $warn) = $self->_check_value(@args); |
987
|
|
|
|
|
|
|
$self->_check_mandatory_value(@args, value => $value, error => $error); |
988
|
4513
|
|
|
|
|
13240
|
$self->clear_errors; |
989
|
|
|
|
|
|
|
$self->clear_warnings; |
990
|
|
|
|
|
|
|
$self->add_error(@$error) if @$error; |
991
|
|
|
|
|
|
|
$self->add_warning(@$warn) if @$warn; |
992
|
|
|
|
|
|
|
|
993
|
|
|
|
|
|
|
$logger->trace("done"); |
994
|
4513
|
|
|
|
|
42248
|
|
995
|
|
|
|
|
|
|
my $ok = not $error->@*; |
996
|
|
|
|
|
|
|
# return $value because it may be updated by apply_fix |
997
|
4406
|
|
|
4406
|
|
5885
|
return wantarray ? ($ok, $value) : $ok; |
|
4406
|
|
|
|
|
5649
|
|
|
4406
|
|
|
|
|
11998
|
|
|
4406
|
|
|
|
|
5558
|
|
998
|
4406
|
|
|
|
|
7274
|
} |
999
|
4406
|
|
100
|
|
|
11453
|
|
1000
|
4406
|
|
100
|
|
|
10746
|
my ( $self, $value_r, $apply_fix, $array, $label, $sub, $msg, $fix ) = @_; |
1001
|
4406
|
|
33
|
|
|
9435
|
|
1002
|
|
|
|
|
|
|
$logger->info( $self->location . ": run_code_on_value called (apply_fix $apply_fix)" ); |
1003
|
|
|
|
|
|
|
|
1004
|
4406
|
100
|
100
|
|
|
14188
|
my $ret = $sub->($$value_r); |
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
1005
|
|
|
|
|
|
|
if ( $logger->is_debug ) { |
1006
|
|
|
|
|
|
|
my $str = defined $ret ? $ret : '<undef>'; |
1007
|
|
|
|
|
|
|
$logger->debug("run_code_on_value sub returned '$str'"); |
1008
|
|
|
|
|
|
|
} |
1009
|
|
|
|
|
|
|
|
1010
|
|
|
|
|
|
|
unless ($ret) { |
1011
|
14
|
|
|
|
|
40
|
$logger->debug("run_code_on_value sub returned false"); |
1012
|
|
|
|
|
|
|
$msg =~ s/\$_/$$value_r/g if defined $$value_r; |
1013
|
14
|
50
|
|
|
|
64
|
if ($msg =~ /\$std_value/) { |
1014
|
14
|
|
|
|
|
50
|
my $std = $self->_fetch_std_no_check ; |
1015
|
|
|
|
|
|
|
$msg =~ s/\$std_value/$std/g if defined $std; |
1016
|
|
|
|
|
|
|
} |
1017
|
4406
|
|
|
|
|
9071
|
$msg .= " (this cannot be fixed with 'cme fix' command)" unless $fix; |
1018
|
|
|
|
|
|
|
push @$array, $msg unless $apply_fix; |
1019
|
|
|
|
|
|
|
$self->{nb_of_fixes}++ if ( defined $fix and not $apply_fix ); |
1020
|
4406
|
|
|
4406
|
1
|
6803
|
$self->apply_fix( $fix, $value_r, $msg ) if ( defined $fix and $apply_fix ); |
|
4406
|
|
|
|
|
5928
|
|
|
4406
|
|
|
|
|
8317
|
|
|
4406
|
|
|
|
|
5292
|
|
1021
|
4406
|
|
|
|
|
10967
|
} |
1022
|
4406
|
|
|
|
|
13635
|
return; |
1023
|
4406
|
|
|
|
|
14240
|
} |
1024
|
4406
|
|
|
|
|
45045
|
|
1025
|
4406
|
100
|
|
|
|
34017
|
# function that may be used in eval'ed code to use file in there (in |
1026
|
4406
|
100
|
|
|
|
9137
|
# run_code_set_on_value and apply_fix). Using this function is |
1027
|
|
|
|
|
|
|
# mandatory for tests that are done in pseudo root |
1028
|
4406
|
|
|
|
|
13476
|
# directory. Necessary for relative path (although chdir in and out of |
1029
|
|
|
|
|
|
|
# root_dir could work) and for absolute path (where chdir in and out |
1030
|
4406
|
|
|
|
|
28215
|
# of root_dir would not work without using chroot) |
1031
|
|
|
|
|
|
|
|
1032
|
4406
|
100
|
|
|
|
15546
|
{ |
1033
|
|
|
|
|
|
|
# val is a value object. Use this trick so eval'ed code can |
1034
|
|
|
|
|
|
|
# use file() function instead of $file->() sub ref |
1035
|
|
|
|
|
|
|
my $val ; |
1036
|
184
|
|
|
184
|
0
|
361
|
return $val = shift; |
1037
|
|
|
|
|
|
|
} |
1038
|
184
|
|
|
|
|
820
|
return $val->root_path->child(shift); |
1039
|
|
|
|
|
|
|
} |
1040
|
184
|
|
|
|
|
1486
|
} |
1041
|
184
|
100
|
|
|
|
495
|
|
1042
|
83
|
50
|
|
|
|
329
|
my ( $self, $value_r, $apply_fix, $array, $w_info, $invert ) = @_; |
1043
|
83
|
|
|
|
|
229
|
|
1044
|
|
|
|
|
|
|
$self->set_val; |
1045
|
|
|
|
|
|
|
|
1046
|
184
|
100
|
|
|
|
1456
|
foreach my $label ( sort keys %$w_info ) { |
1047
|
97
|
|
|
|
|
223
|
my $code = $w_info->{$label}{code}; |
1048
|
97
|
100
|
|
|
|
868
|
my $msg = $w_info->{$label}{msg} || $label; |
1049
|
97
|
100
|
|
|
|
221
|
$logger->trace("eval'ed code is: '$code'"); |
1050
|
6
|
|
|
|
|
20
|
my $fix = $w_info->{$label}{fix}; |
1051
|
6
|
100
|
|
|
|
31
|
|
1052
|
|
|
|
|
|
|
my $sub = sub { |
1053
|
97
|
50
|
|
|
|
164
|
local $_ = shift; |
1054
|
97
|
100
|
|
|
|
214
|
## no critic (TestingAndDebugging::ProhibitNoWarning) |
1055
|
97
|
100
|
66
|
|
|
332
|
no warnings "uninitialized"; |
1056
|
97
|
100
|
66
|
|
|
299
|
my $ret = eval($code); ## no critic (ProhibitStringyEval) |
1057
|
|
|
|
|
|
|
if ($@) { |
1058
|
184
|
|
|
|
|
764
|
Config::Model::Exception::Model->throw( |
1059
|
|
|
|
|
|
|
object => $self, |
1060
|
|
|
|
|
|
|
message => "Eval of assert or warning code failed : $@" |
1061
|
|
|
|
|
|
|
); |
1062
|
|
|
|
|
|
|
} |
1063
|
|
|
|
|
|
|
return ($invert xor $ret) ; |
1064
|
|
|
|
|
|
|
}; |
1065
|
|
|
|
|
|
|
|
1066
|
|
|
|
|
|
|
$self->run_code_on_value( $value_r, $apply_fix, $array, $label, $sub, $msg, $fix ); |
1067
|
|
|
|
|
|
|
} |
1068
|
|
|
|
|
|
|
return; |
1069
|
|
|
|
|
|
|
} |
1070
|
|
|
|
|
|
|
|
1071
|
|
|
|
|
|
|
my ( $self, $value_r, $apply_fix, $array, $may_be, $test_sub, $w_info ) = @_; |
1072
|
|
|
|
|
|
|
|
1073
|
112
|
|
|
112
|
0
|
155
|
# no need to check default or computed values |
1074
|
|
|
|
|
|
|
return unless defined $$value_r; |
1075
|
|
|
|
|
|
|
|
1076
|
4
|
|
|
4
|
1
|
20
|
foreach my $rxp ( sort keys %$w_info ) { |
1077
|
|
|
|
|
|
|
# $_[0] is set to $$value_r when $sub is called |
1078
|
|
|
|
|
|
|
my $sub = sub { $test_sub->( $_[0], $rxp ) }; |
1079
|
|
|
|
|
|
|
my $msg = $w_info->{$rxp}{msg} || "value should ${may_be}match regexp '$rxp'"; |
1080
|
|
|
|
|
|
|
my $fix = $w_info->{$rxp}{fix}; |
1081
|
75
|
|
|
75
|
0
|
149
|
$self->run_code_on_value( $value_r, $apply_fix, $array, 'regexp', $sub, $msg, $fix ); |
1082
|
|
|
|
|
|
|
} |
1083
|
75
|
|
|
|
|
160
|
return |
1084
|
|
|
|
|
|
|
} |
1085
|
75
|
|
|
|
|
227
|
|
1086
|
75
|
|
|
|
|
128
|
my $self = shift; |
1087
|
75
|
|
33
|
|
|
158
|
return $self->{nb_of_fixes}; |
1088
|
75
|
|
|
|
|
291
|
} |
1089
|
75
|
|
|
|
|
729
|
|
1090
|
|
|
|
|
|
|
my $self = shift; |
1091
|
|
|
|
|
|
|
|
1092
|
75
|
|
|
75
|
|
121
|
if ( $logger->is_trace ) { |
1093
|
|
|
|
|
|
|
$fix_logger->trace( "called for " . $self->location ); |
1094
|
59
|
|
|
59
|
|
666
|
} |
|
59
|
|
|
|
|
138
|
|
|
59
|
|
|
|
|
38316
|
|
1095
|
75
|
|
|
|
|
5071
|
|
1096
|
75
|
50
|
|
|
|
767
|
my ( $old, $new ); |
1097
|
0
|
|
|
|
|
0
|
my $i = 0; |
1098
|
|
|
|
|
|
|
do { |
1099
|
|
|
|
|
|
|
$old = $self->{nb_of_fixes} // 0; |
1100
|
|
|
|
|
|
|
$self->check_value( value => $self->_fetch_no_check, fix => 1 ); |
1101
|
|
|
|
|
|
|
|
1102
|
75
|
|
100
|
|
|
299
|
$new = $self->{nb_of_fixes}; |
1103
|
75
|
|
|
|
|
288
|
$self->check_value( value => $self->_fetch_no_check ); |
1104
|
|
|
|
|
|
|
# if fix fails, try and check_fix call each other until this limit is found |
1105
|
75
|
|
|
|
|
178
|
if ( $i++ > 20 ) { |
1106
|
|
|
|
|
|
|
Config::Model::Exception::Model->throw( |
1107
|
75
|
|
|
|
|
136
|
object => $self, |
1108
|
|
|
|
|
|
|
error => "Too many fix loops: check code used to fix value or the check" |
1109
|
|
|
|
|
|
|
); |
1110
|
|
|
|
|
|
|
} |
1111
|
121
|
|
|
121
|
0
|
233
|
} while ( $self->{nb_of_fixes} and $old > $new ); |
1112
|
|
|
|
|
|
|
|
1113
|
|
|
|
|
|
|
$self->show_warnings($self->_fetch_no_check); |
1114
|
121
|
100
|
|
|
|
273
|
return; |
1115
|
|
|
|
|
|
|
} |
1116
|
97
|
|
|
|
|
269
|
|
1117
|
|
|
|
|
|
|
# internal: called by check when a fix is required |
1118
|
109
|
|
|
109
|
|
282
|
my ( $self, $fix, $value_r, $msg ) = @_; |
|
109
|
|
|
|
|
201
|
|
1119
|
109
|
|
66
|
|
|
291
|
|
1120
|
109
|
|
|
|
|
156
|
local $_ = $$value_r; # used inside $fix sub ref |
1121
|
109
|
|
|
|
|
206
|
|
1122
|
|
|
|
|
|
|
if ( $fix_logger->is_info ) { |
1123
|
|
|
|
|
|
|
my $str = $fix; |
1124
|
97
|
|
|
|
|
260
|
$str =~ s/\n/ /g; |
1125
|
|
|
|
|
|
|
$fix_logger->info( $self->location . ": Applying fix '$str'" ); |
1126
|
|
|
|
|
|
|
} |
1127
|
9
|
|
|
9
|
1
|
2802
|
|
1128
|
9
|
|
|
|
|
33
|
$self->set_val; |
1129
|
|
|
|
|
|
|
|
1130
|
|
|
|
|
|
|
eval($fix); ## no critic (ProhibitStringyEval) |
1131
|
|
|
|
|
|
|
if ($@) { |
1132
|
94
|
|
|
94
|
1
|
1939
|
Config::Model::Exception::Model->throw( |
1133
|
|
|
|
|
|
|
object => $self, |
1134
|
94
|
100
|
|
|
|
210
|
message => "Eval of fix $fix failed : $@" |
1135
|
4
|
|
|
|
|
29
|
); |
1136
|
|
|
|
|
|
|
} |
1137
|
|
|
|
|
|
|
|
1138
|
94
|
|
|
|
|
605
|
## no critic (TestingAndDebugging::ProhibitNoWarning) |
1139
|
94
|
|
|
|
|
122
|
no warnings "uninitialized"; |
1140
|
|
|
|
|
|
|
if ( $_ ne $$value_r ) { |
1141
|
94
|
|
100
|
|
|
220
|
$fix_logger->info( $self->location . ": fix changed value from '$$value_r' to '$_'" ); |
1142
|
94
|
|
|
|
|
198
|
$self->_store_fix( $$value_r, $_, $msg ); |
1143
|
|
|
|
|
|
|
$$value_r = $_; # so chain of fixes work |
1144
|
94
|
|
|
|
|
148
|
} |
1145
|
94
|
|
|
|
|
181
|
else { |
1146
|
|
|
|
|
|
|
$fix_logger->info( $self->location . ": fix did not change value '$$value_r'" ); |
1147
|
94
|
50
|
|
|
|
320
|
} |
1148
|
0
|
|
|
|
|
0
|
return; |
1149
|
|
|
|
|
|
|
} |
1150
|
|
|
|
|
|
|
|
1151
|
|
|
|
|
|
|
my ( $self, $old, $new, $msg ) = @_; |
1152
|
|
|
|
|
|
|
|
1153
|
94
|
|
66
|
|
|
115
|
$self->{data} = $new; |
1154
|
|
|
|
|
|
|
|
1155
|
94
|
|
|
|
|
202
|
if ( $fix_logger->is_trace ) { |
1156
|
94
|
|
|
|
|
376
|
$fix_logger->trace( |
1157
|
|
|
|
|
|
|
"fix change: '" . ( $old // '<undef>' ) . "' -> '" . ( $new // '<undef>' ) . "'" |
1158
|
|
|
|
|
|
|
); |
1159
|
|
|
|
|
|
|
} |
1160
|
|
|
|
|
|
|
|
1161
|
37
|
|
|
37
|
0
|
76
|
my $new_v = $new // $self->_fetch_std ; |
1162
|
|
|
|
|
|
|
my $old_v = $old // $self->_fetch_std; |
1163
|
37
|
|
|
|
|
60
|
|
1164
|
|
|
|
|
|
|
if ( $fix_logger->is_trace ) { |
1165
|
37
|
100
|
|
|
|
76
|
$fix_logger->trace( |
1166
|
4
|
|
|
|
|
15
|
"fix change (with std value)): '" . ( $old // '<undef>' ) . "' -> '" . ( $new // '<undef>' ) . "'" |
1167
|
4
|
|
|
|
|
7
|
); |
1168
|
4
|
|
|
|
|
22
|
} |
1169
|
|
|
|
|
|
|
|
1170
|
|
|
|
|
|
|
## no critic (TestingAndDebugging::ProhibitNoWarning) |
1171
|
37
|
|
|
|
|
238
|
no warnings "uninitialized"; |
1172
|
|
|
|
|
|
|
# in case $old is the default value and $new is undef |
1173
|
37
|
|
|
|
|
2609
|
if ($old_v ne $new_v) { |
1174
|
37
|
50
|
|
|
|
193
|
$self->notify_change( |
1175
|
0
|
|
|
|
|
0
|
old => $old_v, |
1176
|
|
|
|
|
|
|
new => $new_v, |
1177
|
|
|
|
|
|
|
note => 'applied fix'. ( $msg ? ' for :'. $msg : '') |
1178
|
|
|
|
|
|
|
); |
1179
|
|
|
|
|
|
|
$self->trigger_warp($new_v) if defined $new_v and $self->has_warped_slaves; |
1180
|
|
|
|
|
|
|
} |
1181
|
|
|
|
|
|
|
return; |
1182
|
59
|
|
|
59
|
|
412
|
} |
|
59
|
|
|
|
|
123
|
|
|
59
|
|
|
|
|
15345
|
|
1183
|
37
|
100
|
|
|
|
94
|
|
1184
|
34
|
|
|
|
|
209
|
# read checks should be blocking |
1185
|
34
|
|
|
|
|
300
|
|
1186
|
34
|
|
|
|
|
59
|
goto &check_fetched_value; |
1187
|
|
|
|
|
|
|
} |
1188
|
|
|
|
|
|
|
|
1189
|
3
|
|
|
|
|
15
|
if ( $logger->is_debug ) { |
1190
|
|
|
|
|
|
|
## no critic (TestingAndDebugging::ProhibitNoWarning) |
1191
|
37
|
|
|
|
|
80
|
no warnings 'uninitialized'; |
1192
|
|
|
|
|
|
|
$logger->debug( "called for " . $self->location . " from " . join( ' ', caller ), |
1193
|
|
|
|
|
|
|
" with @args" ); |
1194
|
|
|
|
|
|
|
} |
1195
|
34
|
|
|
34
|
|
77
|
|
1196
|
|
|
|
|
|
|
my %args = |
1197
|
34
|
|
|
|
|
50
|
@args == 0 ? ( value => $self->{data} ) |
1198
|
|
|
|
|
|
|
: @args == 1 ? ( value => $args[0] ) |
1199
|
34
|
100
|
|
|
|
71
|
: @args; |
1200
|
4
|
|
100
|
|
|
37
|
|
|
|
|
100
|
|
|
|
|
1201
|
|
|
|
|
|
|
my $value = exists $args{value} ? $args{value} : $self->{data}; |
1202
|
|
|
|
|
|
|
my $silent = $args{silent} || 0; |
1203
|
|
|
|
|
|
|
my $check = $args{check} || 'yes'; |
1204
|
|
|
|
|
|
|
|
1205
|
34
|
|
100
|
|
|
245
|
if ( $self->needs_check ) { |
1206
|
34
|
|
66
|
|
|
66
|
$self->check_value(%args); |
1207
|
|
|
|
|
|
|
|
1208
|
34
|
100
|
|
|
|
67
|
my $err_count = $self->has_error; |
1209
|
4
|
|
100
|
|
|
31
|
my $warn_count = $self->has_warning; |
|
|
|
100
|
|
|
|
|
1210
|
|
|
|
|
|
|
$logger->debug("done with $err_count errors and $warn_count warnings"); |
1211
|
|
|
|
|
|
|
|
1212
|
|
|
|
|
|
|
$self->needs_check(0) unless $err_count or $warn_count; |
1213
|
|
|
|
|
|
|
} |
1214
|
|
|
|
|
|
|
else { |
1215
|
59
|
|
|
59
|
|
402
|
$logger->debug("is not needed"); |
|
59
|
|
|
|
|
120
|
|
|
59
|
|
|
|
|
10368
|
|
1216
|
|
|
|
|
|
|
} |
1217
|
34
|
100
|
|
|
|
193
|
|
1218
|
33
|
50
|
|
|
|
157
|
$self->show_warnings($value, $silent); |
1219
|
|
|
|
|
|
|
|
1220
|
|
|
|
|
|
|
return wantarray ? $self->all_errors : $self->is_ok; |
1221
|
|
|
|
|
|
|
} |
1222
|
|
|
|
|
|
|
|
1223
|
33
|
100
|
100
|
|
|
112
|
# old_warn is used to avoid warning the user several times for the |
1224
|
|
|
|
|
|
|
# same reason (i.e. when storing and fetching value). We take care |
1225
|
34
|
|
|
|
|
214
|
# to clean up this hash each time store is run |
1226
|
|
|
|
|
|
|
my $old_warn = $self->{old_warning_hash} || {}; |
1227
|
|
|
|
|
|
|
my %warn_h; |
1228
|
|
|
|
|
|
|
|
1229
|
|
|
|
|
|
|
if ( $self->has_warning and not $nowarning and not $silent ) { |
1230
|
|
|
|
|
|
|
my $str = $value // '<undef>'; |
1231
|
6544
|
|
|
6544
|
1
|
17807
|
chomp $str; |
1232
|
|
|
|
|
|
|
my $w_str = $str =~ /\n/ ? "\n+++++\n$str\n+++++" : "'$str'"; |
1233
|
|
|
|
|
|
|
foreach my $w ( $self->all_warnings ) { |
1234
|
6544
|
|
|
6544
|
0
|
8236
|
$warn_h{$w} = 1; |
|
6544
|
|
|
|
|
7790
|
|
|
6544
|
|
|
|
|
11765
|
|
|
6544
|
|
|
|
|
7535
|
|
1235
|
6544
|
100
|
|
|
|
12940
|
my $w_msg = "Warning in '" . $self->location_short . "': $w\nOffending value: $w_str"; |
1236
|
|
|
|
|
|
|
if ($old_warn->{$w}) { |
1237
|
59
|
|
|
59
|
|
433
|
# user has already seen the warning, let's use debug level (required by tests) |
|
59
|
|
|
|
|
137
|
|
|
59
|
|
|
|
|
35715
|
|
1238
|
62
|
|
|
|
|
407
|
$user_logger->debug($w_msg); |
1239
|
|
|
|
|
|
|
} |
1240
|
|
|
|
|
|
|
else { |
1241
|
|
|
|
|
|
|
$user_logger->warn($w_msg); |
1242
|
|
|
|
|
|
|
} |
1243
|
|
|
|
|
|
|
} |
1244
|
6544
|
50
|
|
|
|
45136
|
} |
|
|
100
|
|
|
|
|
|
1245
|
|
|
|
|
|
|
$self->{old_warning_hash} = \%warn_h; |
1246
|
|
|
|
|
|
|
return; |
1247
|
6544
|
50
|
|
|
|
14795
|
} |
1248
|
6544
|
|
50
|
|
|
16973
|
|
1249
|
6544
|
|
50
|
|
|
14725
|
my %args = |
1250
|
|
|
|
|
|
|
@args == 1 ? ( value => $args[0] ) |
1251
|
6544
|
100
|
|
|
|
15540
|
: @args == 3 ? ( 'value', @args ) |
1252
|
1716
|
|
|
|
|
42440
|
: @args; |
1253
|
|
|
|
|
|
|
my $check = $self->_check_check( $args{check} ); |
1254
|
1716
|
|
|
|
|
4468
|
my $silent = $args{silent} || 0; |
1255
|
1716
|
|
|
|
|
11146
|
|
1256
|
1716
|
|
|
|
|
12368
|
my $str = $args{value} // '<undef>'; |
1257
|
|
|
|
|
|
|
$logger->debug( "called with '$str' on ", $self->composite_name ) if $logger->is_debug; |
1258
|
1716
|
100
|
100
|
|
|
14894
|
|
1259
|
|
|
|
|
|
|
# store with check skip makes sense when force loading data: bad value |
1260
|
|
|
|
|
|
|
# is discarded, partially consistent values are stored so the user may |
1261
|
4828
|
|
|
|
|
119795
|
# salvage them before next save check discard them |
1262
|
|
|
|
|
|
|
|
1263
|
|
|
|
|
|
|
# $self->{data} represents what written in the file |
1264
|
6544
|
|
|
|
|
78898
|
my $old_value = $self->{data}; |
1265
|
|
|
|
|
|
|
|
1266
|
6544
|
50
|
|
|
|
16507
|
my $incoming_value = $args{value}; |
1267
|
|
|
|
|
|
|
$self->transform_boolean( \$incoming_value ) if $self->value_type eq 'boolean'; |
1268
|
|
|
|
|
|
|
|
1269
|
8484
|
|
|
8484
|
0
|
10728
|
my $value = $self->transform_value( value => $incoming_value, check => $check ); |
|
8484
|
|
|
|
|
10688
|
|
|
8484
|
|
|
|
|
12294
|
|
|
8484
|
|
|
|
|
12174
|
|
|
8484
|
|
|
|
|
9600
|
|
1270
|
|
|
|
|
|
|
|
1271
|
|
|
|
|
|
|
## no critic (TestingAndDebugging::ProhibitNoWarning) |
1272
|
|
|
|
|
|
|
no warnings qw/uninitialized/; |
1273
|
8484
|
|
100
|
|
|
22775
|
if ($self->instance->initial_load) { |
1274
|
8484
|
|
|
|
|
10744
|
# may send more than one notification |
1275
|
|
|
|
|
|
|
if ( $incoming_value ne $value ) { |
1276
|
8484
|
100
|
100
|
|
|
17672
|
# data was transformed by model |
|
|
|
66
|
|
|
|
|
1277
|
47
|
|
100
|
|
|
448
|
$self->notify_change(really => 1, old => $incoming_value , new => $value, note =>"initial value changed by model"); |
1278
|
47
|
|
|
|
|
85
|
} |
1279
|
47
|
100
|
|
|
|
147
|
if (defined $old_value and $old_value ne $value) { |
1280
|
47
|
|
|
|
|
121
|
$self->notify_change(really => 1, old => $old_value , new => $value, note =>"conflicting initial values"); |
1281
|
53
|
|
|
|
|
599
|
} |
1282
|
53
|
|
|
|
|
273
|
if (defined $old_value and $old_value eq $value) { |
1283
|
53
|
100
|
|
|
|
144
|
$self->notify_change(really => 1, note =>"removed redundant initial value"); |
1284
|
|
|
|
|
|
|
} |
1285
|
7
|
|
|
|
|
17
|
} |
1286
|
|
|
|
|
|
|
|
1287
|
|
|
|
|
|
|
if ( defined $old_value and $value eq $old_value ) { |
1288
|
46
|
|
|
|
|
133
|
$logger->info( "skip storage of ", $self->composite_name, " unchanged value: $value" ) |
1289
|
|
|
|
|
|
|
if $logger->is_info; |
1290
|
|
|
|
|
|
|
return 1; |
1291
|
|
|
|
|
|
|
} |
1292
|
8484
|
|
|
|
|
61081
|
|
1293
|
8484
|
|
|
|
|
15111
|
use warnings qw/uninitialized/; |
1294
|
|
|
|
|
|
|
|
1295
|
|
|
|
|
|
|
$self->needs_check(1); # always when storing a value |
1296
|
1917
|
|
|
1917
|
1
|
41528
|
|
|
1917
|
|
|
|
|
2877
|
|
|
1917
|
|
|
|
|
3575
|
|
|
1917
|
|
|
|
|
2460
|
|
1297
|
1917
|
50
|
|
|
|
7928
|
my ($ok, $fixed_value) = $self->check_stored_value( |
|
|
100
|
|
|
|
|
|
1298
|
|
|
|
|
|
|
value => $value, |
1299
|
|
|
|
|
|
|
check => $check, |
1300
|
|
|
|
|
|
|
silent => $silent, |
1301
|
1917
|
|
|
|
|
6332
|
); |
1302
|
1917
|
|
100
|
|
|
6702
|
|
1303
|
|
|
|
|
|
|
$self->_store( %args, ok => $ok, value => $value, check => $check ); |
1304
|
1917
|
|
100
|
|
|
4652
|
|
1305
|
1917
|
100
|
|
|
|
4774
|
my $user_cb = $args{callback} ; |
1306
|
|
|
|
|
|
|
$user_cb->(%args) if $user_cb; |
1307
|
|
|
|
|
|
|
|
1308
|
|
|
|
|
|
|
return $ok || ($check eq 'no'); |
1309
|
|
|
|
|
|
|
} |
1310
|
|
|
|
|
|
|
|
1311
|
|
|
|
|
|
|
# |
1312
|
1917
|
|
|
|
|
11595
|
# New subroutine "_store_value" extracted - Wed Jan 16 18:46:22 2013. |
1313
|
|
|
|
|
|
|
# |
1314
|
1917
|
|
|
|
|
3217
|
my $self = shift; |
1315
|
1917
|
100
|
|
|
|
6946
|
my $value = shift; |
1316
|
|
|
|
|
|
|
my $notify_change = shift // 1; |
1317
|
1917
|
|
|
|
|
5802
|
|
1318
|
|
|
|
|
|
|
if ( $self->instance->layered ) { |
1319
|
|
|
|
|
|
|
$self->{layered} = $value; |
1320
|
59
|
|
|
59
|
|
422
|
} |
|
59
|
|
|
|
|
117
|
|
|
59
|
|
|
|
|
11499
|
|
1321
|
1916
|
100
|
|
|
|
8399
|
elsif ( $self->instance->preset ) { |
1322
|
|
|
|
|
|
|
$self->notify_change( check_done => 1, old => $self->{data}, new => $value ) |
1323
|
804
|
100
|
|
|
|
2098
|
if $notify_change; |
1324
|
|
|
|
|
|
|
$self->{preset} = $value; |
1325
|
21
|
|
|
|
|
74
|
} |
1326
|
|
|
|
|
|
|
else { |
1327
|
804
|
100
|
100
|
|
|
2257
|
## no critic (TestingAndDebugging::ProhibitNoWarning) |
1328
|
1
|
|
|
|
|
4
|
no warnings 'uninitialized'; |
1329
|
|
|
|
|
|
|
my $old = $self->{data} // $self->_fetch_std; |
1330
|
804
|
100
|
100
|
|
|
1700
|
my $new = $value // $self->_fetch_std; |
1331
|
2
|
|
|
|
|
7
|
$self->notify_change( |
1332
|
|
|
|
|
|
|
check_done => 1, |
1333
|
|
|
|
|
|
|
old => $old, |
1334
|
|
|
|
|
|
|
new => $new |
1335
|
1916
|
100
|
100
|
|
|
4945
|
) if $notify_change and ( $old ne $new ); |
1336
|
70
|
100
|
|
|
|
232
|
$self->{data} = $value; # may be undef |
1337
|
|
|
|
|
|
|
} |
1338
|
70
|
|
|
|
|
935
|
return $value; |
1339
|
|
|
|
|
|
|
} |
1340
|
|
|
|
|
|
|
|
1341
|
59
|
|
|
59
|
|
375
|
# this method is overriden in layered Value |
|
59
|
|
|
|
|
112
|
|
|
59
|
|
|
|
|
12283
|
|
1342
|
|
|
|
|
|
|
my ( $value, $check, $silent, $notify_change, $ok ) = |
1343
|
1846
|
|
|
|
|
5911
|
@args{qw/value check silent notify_change ok/}; |
1344
|
|
|
|
|
|
|
|
1345
|
1846
|
|
|
|
|
38913
|
if ( $logger->is_debug ) { |
1346
|
|
|
|
|
|
|
my $i = $self->instance; |
1347
|
|
|
|
|
|
|
my $msg = "value store ". ($value // '<undef>')." ok '$ok', check is $check"; |
1348
|
|
|
|
|
|
|
for ( qw/layered preset/ ) { $msg .= " $_" if $i->$_() } |
1349
|
|
|
|
|
|
|
$logger->debug($msg); |
1350
|
|
|
|
|
|
|
} |
1351
|
1846
|
|
|
|
|
7087
|
|
1352
|
|
|
|
|
|
|
my $old_value = $self->_fetch_no_check; |
1353
|
1842
|
|
|
|
|
3595
|
|
1354
|
1842
|
100
|
|
|
|
3587
|
# let's store wrong value when check is disable (gh #15) |
1355
|
|
|
|
|
|
|
if ( $ok or $check eq 'no' ) { |
1356
|
1842
|
|
100
|
|
|
11208
|
$self->instance->cancel_error( $self->location ); |
1357
|
|
|
|
|
|
|
$self->_store_value( $value, $notify_change ); |
1358
|
|
|
|
|
|
|
} |
1359
|
|
|
|
|
|
|
else { |
1360
|
|
|
|
|
|
|
$self->instance->add_error( $self->location ); |
1361
|
|
|
|
|
|
|
if ($check eq 'skip') { |
1362
|
|
|
|
|
|
|
if (not $silent and $self->has_error) { |
1363
|
1831
|
|
|
1831
|
|
2695
|
my $msg = "Warning: ".$self->location." skipping value $value because of the following errors:\n" |
1364
|
1831
|
|
|
|
|
2921
|
. $self->error_msg . "\n\n"; |
1365
|
1831
|
|
50
|
|
|
5502
|
# fuse UI exits when a warning is issued. No other need to advertise this option |
1366
|
|
|
|
|
|
|
print $msg if $args{say_dont_warn}; |
1367
|
1831
|
100
|
|
|
|
9131
|
$user_logger->warn($msg) unless $args{say_dont_warn}; |
|
|
100
|
|
|
|
|
|
1368
|
133
|
|
|
|
|
368
|
} |
1369
|
|
|
|
|
|
|
} |
1370
|
|
|
|
|
|
|
else { |
1371
|
11
|
50
|
|
|
|
71
|
Config::Model::Exception::WrongValue->throw( |
1372
|
|
|
|
|
|
|
object => $self, |
1373
|
11
|
|
|
|
|
31
|
error => $self->error_msg |
1374
|
|
|
|
|
|
|
); |
1375
|
|
|
|
|
|
|
} |
1376
|
|
|
|
|
|
|
} |
1377
|
59
|
|
|
59
|
|
401
|
|
|
59
|
|
|
|
|
112
|
|
|
59
|
|
|
|
|
141091
|
|
1378
|
1687
|
|
100
|
|
|
6330
|
if ( $ok |
1379
|
1687
|
|
100
|
|
|
3900
|
and defined $value |
1380
|
1687
|
100
|
66
|
|
|
9546
|
and $self->has_warped_slaves |
1381
|
|
|
|
|
|
|
and ( not defined $old_value or $value ne $old_value ) |
1382
|
|
|
|
|
|
|
and not( $self->instance->layered or $self->instance->preset ) ) { |
1383
|
|
|
|
|
|
|
$self->trigger_warp($value); |
1384
|
|
|
|
|
|
|
} |
1385
|
1687
|
|
|
|
|
4002
|
|
1386
|
|
|
|
|
|
|
$logger->trace( "_store done on ", $self->composite_name ) if $logger->is_trace; |
1387
|
1831
|
|
|
|
|
4403
|
return; |
1388
|
|
|
|
|
|
|
} |
1389
|
|
|
|
|
|
|
|
1390
|
|
|
|
|
|
|
# |
1391
|
1846
|
|
|
1846
|
|
2557
|
# New subroutine "transform_boolean" extracted - Thu Sep 19 18:58:21 2013. |
|
1846
|
|
|
|
|
4185
|
|
|
1846
|
|
|
|
|
6029
|
|
|
1846
|
|
|
|
|
2325
|
|
1392
|
|
|
|
|
|
|
# |
1393
|
1846
|
|
|
|
|
5894
|
my $self = shift; |
1394
|
|
|
|
|
|
|
my $v_ref = shift; |
1395
|
1846
|
100
|
|
|
|
4460
|
|
1396
|
105
|
|
|
|
|
437
|
return unless defined $$v_ref; |
1397
|
105
|
|
100
|
|
|
373
|
|
1398
|
105
|
100
|
|
|
|
219
|
if ( my $wa = $self->{write_as} ) { |
|
210
|
|
|
|
|
614
|
|
1399
|
105
|
|
|
|
|
230
|
my $i = 0; |
1400
|
|
|
|
|
|
|
for ( @$wa ) { |
1401
|
|
|
|
|
|
|
$$v_ref = $i if ( $wa->[$i] eq $$v_ref ); |
1402
|
1846
|
|
|
|
|
15312
|
$i++ |
1403
|
|
|
|
|
|
|
} |
1404
|
|
|
|
|
|
|
} |
1405
|
1846
|
100
|
100
|
|
|
4778
|
|
1406
|
1826
|
|
|
|
|
10580
|
# convert yes no to 1 or 0 |
1407
|
1826
|
|
|
|
|
24755
|
$$v_ref = 1 if ( $$v_ref =~ /^(y|yes|true|on)$/i ); |
1408
|
|
|
|
|
|
|
$$v_ref = 0 if ( $$v_ref =~ /^(n|no|false|off)$/i or length($$v_ref) == 0); |
1409
|
|
|
|
|
|
|
return; |
1410
|
20
|
|
|
|
|
150
|
} |
1411
|
20
|
100
|
|
|
|
897
|
|
1412
|
17
|
100
|
66
|
|
|
86
|
# internal. return ( undef, value) |
1413
|
5
|
|
|
|
|
69
|
# May return an undef value if actual store should be skipped |
1414
|
|
|
|
|
|
|
my %args = @args > 1 ? @args : ( value => $args[0] ); |
1415
|
|
|
|
|
|
|
my $value = $args{value}; |
1416
|
5
|
50
|
|
|
|
19
|
my $check = $args{check} || 'yes'; |
1417
|
5
|
50
|
|
|
|
32
|
|
1418
|
|
|
|
|
|
|
my $inst = $self->instance; |
1419
|
|
|
|
|
|
|
|
1420
|
|
|
|
|
|
|
$self->warp |
1421
|
3
|
|
|
|
|
16
|
if ($self->{warp} |
1422
|
|
|
|
|
|
|
and defined $self->{warp_info} |
1423
|
|
|
|
|
|
|
and @{ $self->{warp_info}{computed_master} } ); |
1424
|
|
|
|
|
|
|
|
1425
|
|
|
|
|
|
|
if ( defined $self->compute_obj |
1426
|
|
|
|
|
|
|
and not $self->compute_obj->allow_user_override ) { |
1427
|
|
|
|
|
|
|
my $msg = 'assignment to a computed value is forbidden unless ' |
1428
|
1843
|
50
|
100
|
|
|
9995
|
. 'compute -> allow_override is set.'; |
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
1429
|
|
|
|
|
|
|
Config::Model::Exception::Model->throw( object => $self, message => $msg ) |
1430
|
|
|
|
|
|
|
if $check eq 'yes'; |
1431
|
|
|
|
|
|
|
return; |
1432
|
|
|
|
|
|
|
} |
1433
|
100
|
|
|
|
|
2081
|
|
1434
|
|
|
|
|
|
|
if ( defined $self->{refer_to} or defined $self->{computed_refer_to} ) { |
1435
|
|
|
|
|
|
|
$self->{ref_object}->get_choice_from_referred_to; |
1436
|
1842
|
100
|
|
|
|
14395
|
} |
1437
|
1842
|
|
|
|
|
12418
|
|
1438
|
|
|
|
|
|
|
$value = $self->{convert_sub}($value) |
1439
|
|
|
|
|
|
|
if ( defined $self->{convert_sub} and defined $value ); |
1440
|
|
|
|
|
|
|
|
1441
|
|
|
|
|
|
|
# apply replace on store *before* check is done, so a bad value |
1442
|
|
|
|
|
|
|
# can be replaced with a good one |
1443
|
|
|
|
|
|
|
$value = $self->apply_replace($value) if ($self->{replace} and defined $value); |
1444
|
240
|
|
|
240
|
0
|
435
|
|
1445
|
240
|
|
|
|
|
386
|
# using default or computed value is normally done on fetch. Except that an undefined |
1446
|
|
|
|
|
|
|
# value cannot be stored in a mandatory value. Storing undef is used when resetting a |
1447
|
240
|
100
|
|
|
|
593
|
# value to default. If a value is mandatory, we must store the default (or best equivalent) |
1448
|
|
|
|
|
|
|
# instead |
1449
|
238
|
100
|
|
|
|
708
|
if ( ( not defined $value or not length($value) ) and $self->mandatory ) { |
1450
|
37
|
|
|
|
|
68
|
delete $self->{data}; # avoiding recycling the old stored value |
1451
|
37
|
|
|
|
|
85
|
$value = $self->_fetch_no_check; |
1452
|
74
|
100
|
|
|
|
200
|
} |
1453
|
74
|
|
|
|
|
115
|
|
1454
|
|
|
|
|
|
|
return $value; |
1455
|
|
|
|
|
|
|
} |
1456
|
|
|
|
|
|
|
|
1457
|
|
|
|
|
|
|
my ($self, $value) = @_; |
1458
|
238
|
100
|
|
|
|
1212
|
|
1459
|
238
|
100
|
100
|
|
|
1336
|
if ( defined $self->{replace}{$value} ) { |
1460
|
238
|
|
|
|
|
425
|
$logger->debug("store replacing value $value with $self->{replace}{$value}"); |
1461
|
|
|
|
|
|
|
$value = $self->{replace}{$value}; |
1462
|
|
|
|
|
|
|
} |
1463
|
|
|
|
|
|
|
else { |
1464
|
|
|
|
|
|
|
foreach my $k ( keys %{ $self->{replace} } ) { |
1465
|
1917
|
|
|
1917
|
0
|
2613
|
if ( $value =~ /^$k$/ ) { |
|
1917
|
|
|
|
|
2948
|
|
|
1917
|
|
|
|
|
3815
|
|
|
1917
|
|
|
|
|
2419
|
|
1466
|
1917
|
50
|
|
|
|
6599
|
$logger->debug( |
1467
|
1917
|
|
|
|
|
3844
|
"store replacing value $value (matched /$k/) with $self->{replace}{$k}"); |
1468
|
1917
|
|
50
|
|
|
4627
|
$value = $self->{replace}{$k}; |
1469
|
|
|
|
|
|
|
last; |
1470
|
1917
|
|
|
|
|
5757
|
} |
1471
|
|
|
|
|
|
|
} |
1472
|
|
|
|
|
|
|
} |
1473
|
|
|
|
|
|
|
return $value; |
1474
|
|
|
|
|
|
|
} |
1475
|
1917
|
50
|
66
|
|
|
6417
|
|
|
0
|
|
33
|
|
|
0
|
|
1476
|
|
|
|
|
|
|
my ($ok, $fixed_value) = $self->check_value( %args ); |
1477
|
1917
|
100
|
100
|
|
|
10408
|
|
1478
|
|
|
|
|
|
|
my ( $value, $check, $silent ) = |
1479
|
1
|
|
|
|
|
3
|
@args{qw/value check silent/}; |
1480
|
|
|
|
|
|
|
|
1481
|
1
|
50
|
|
|
|
23
|
$self->needs_check(0) unless $self->has_error or $self->has_warning; |
1482
|
|
|
|
|
|
|
|
1483
|
0
|
|
|
|
|
0
|
# must always warn when storing a value, hence clearing the list |
1484
|
|
|
|
|
|
|
# of already issued warnings |
1485
|
|
|
|
|
|
|
$self->{old_warning_hash} = {}; |
1486
|
1916
|
100
|
100
|
|
|
7745
|
$self->show_warnings($value, $silent); |
1487
|
44
|
|
|
|
|
158
|
|
1488
|
|
|
|
|
|
|
return wantarray ? ($ok,$fixed_value) : $ok; |
1489
|
|
|
|
|
|
|
} |
1490
|
|
|
|
|
|
|
|
1491
|
1916
|
100
|
66
|
|
|
5091
|
# print a hopefully helpful error message when value_type is not |
1492
|
|
|
|
|
|
|
# defined |
1493
|
|
|
|
|
|
|
my $self = shift; |
1494
|
|
|
|
|
|
|
|
1495
|
1916
|
100
|
66
|
|
|
4895
|
Config::Model::Exception::Model->throw( |
1496
|
|
|
|
|
|
|
object => $self, |
1497
|
|
|
|
|
|
|
message => 'value_type is undefined' |
1498
|
|
|
|
|
|
|
) unless defined $self->{warp}; |
1499
|
|
|
|
|
|
|
|
1500
|
|
|
|
|
|
|
my $str = "Item " . $self->{element_name} . " is not available. " . $self->warp_error; |
1501
|
1916
|
100
|
100
|
|
|
10217
|
|
|
|
|
100
|
|
|
|
|
1502
|
2
|
|
|
|
|
6
|
Config::Model::Exception::User->throw( object => $self, message => $str ); |
1503
|
2
|
|
|
|
|
12
|
return; |
1504
|
|
|
|
|
|
|
} |
1505
|
|
|
|
|
|
|
|
1506
|
1916
|
|
|
|
|
6243
|
my %args = @args > 1 ? @args : ( data => $args[0] ); |
1507
|
|
|
|
|
|
|
my $data = delete $args{data} // delete $args{value}; |
1508
|
|
|
|
|
|
|
|
1509
|
|
|
|
|
|
|
my $rd = ref $data; |
1510
|
6
|
|
|
6
|
0
|
22
|
|
1511
|
|
|
|
|
|
|
if ( $rd and any { $rd eq $_ } qw/ARRAY HASH SCALAR/) { |
1512
|
6
|
100
|
|
|
|
24
|
Config::Model::Exception::LoadData->throw( |
1513
|
4
|
|
|
|
|
23
|
object => $self, |
1514
|
4
|
|
|
|
|
30
|
message => "load_data called with non scalar arg", |
1515
|
|
|
|
|
|
|
wrong_data => $data, |
1516
|
|
|
|
|
|
|
); |
1517
|
2
|
|
|
|
|
5
|
} |
|
2
|
|
|
|
|
11
|
|
1518
|
3
|
100
|
|
|
|
57
|
else { |
1519
|
1
|
|
|
|
|
10
|
if ( $logger->is_info ) { |
1520
|
|
|
|
|
|
|
my $str = $data // '<undef>'; |
1521
|
1
|
|
|
|
|
10
|
$logger->info( "Value load_data (", $self->location, ") will store value $str" ); |
1522
|
1
|
|
|
|
|
4
|
} |
1523
|
|
|
|
|
|
|
return $self->store(%args, value => $data); |
1524
|
|
|
|
|
|
|
} |
1525
|
|
|
|
|
|
|
return; |
1526
|
6
|
|
|
|
|
18
|
} |
1527
|
|
|
|
|
|
|
|
1528
|
|
|
|
|
|
|
my $self = shift; |
1529
|
1846
|
|
|
1846
|
0
|
2775
|
return $self->fetch(mode => 'custom'); |
|
1846
|
|
|
|
|
2615
|
|
|
1846
|
|
|
|
|
5015
|
|
|
1846
|
|
|
|
|
2367
|
|
1530
|
1846
|
|
|
|
|
6280
|
} |
1531
|
|
|
|
|
|
|
|
1532
|
|
|
|
|
|
|
my $self = shift; |
1533
|
1846
|
|
|
|
|
5776
|
return $self->fetch(mode => 'standard'); |
1534
|
|
|
|
|
|
|
} |
1535
|
1846
|
100
|
100
|
|
|
6319
|
|
1536
|
|
|
|
|
|
|
my $self = shift; |
1537
|
|
|
|
|
|
|
return (defined $self->fetch(qw/mode custom check no silent 1/)) ? 1 : 0 ; |
1538
|
|
|
|
|
|
|
} |
1539
|
1846
|
|
|
|
|
34923
|
|
1540
|
1846
|
|
|
|
|
6641
|
my $self = shift; |
1541
|
|
|
|
|
|
|
|
1542
|
1846
|
50
|
|
|
|
7997
|
# trigger loop |
1543
|
|
|
|
|
|
|
#$self->{warper} -> trigger if defined $self->{warper} ; |
1544
|
|
|
|
|
|
|
# if ($self->{warp} and defined $self->{warp_info} |
1545
|
|
|
|
|
|
|
# and @{$self->{warp_info}{computed_master}}); |
1546
|
|
|
|
|
|
|
|
1547
|
|
|
|
|
|
|
if ( defined $self->{refer_to} or defined $self->{computed_refer_to} ) { |
1548
|
0
|
|
|
0
|
|
0
|
$self->submit_to_refer_to; |
1549
|
|
|
|
|
|
|
$self->{ref_object}->get_choice_from_referred_to; |
1550
|
|
|
|
|
|
|
} |
1551
|
|
|
|
|
|
|
return; |
1552
|
|
|
|
|
|
|
} |
1553
|
0
|
0
|
|
|
|
0
|
|
1554
|
|
|
|
|
|
|
# returns something that needs to be written to config file |
1555
|
0
|
|
|
|
|
0
|
# unless overridden by user data |
1556
|
|
|
|
|
|
|
my ( $self, $check ) = @_; |
1557
|
0
|
|
|
|
|
0
|
|
1558
|
0
|
|
|
|
|
0
|
if ( not defined $self->{value_type} and $check eq 'yes' ) { |
1559
|
|
|
|
|
|
|
$self->_value_type_error; |
1560
|
|
|
|
|
|
|
} |
1561
|
435
|
|
|
435
|
1
|
581
|
|
|
435
|
|
|
|
|
525
|
|
|
435
|
|
|
|
|
848
|
|
|
435
|
|
|
|
|
504
|
|
1562
|
435
|
100
|
|
|
|
1337
|
# get stored value or computed value or default value |
1563
|
435
|
|
33
|
|
|
1124
|
my $std_value; |
1564
|
|
|
|
|
|
|
|
1565
|
435
|
|
|
|
|
698
|
eval { |
1566
|
|
|
|
|
|
|
$std_value = |
1567
|
435
|
50
|
33
|
0
|
|
1000
|
defined $self->{preset} ? $self->{preset} |
|
0
|
|
|
|
|
0
|
|
1568
|
0
|
|
|
|
|
0
|
: $self->compute_is_default ? $self->perform_compute |
1569
|
|
|
|
|
|
|
: $self->{default}; |
1570
|
|
|
|
|
|
|
}; |
1571
|
|
|
|
|
|
|
|
1572
|
|
|
|
|
|
|
my $e = $@;; |
1573
|
|
|
|
|
|
|
if ( ref($e) and $e->isa('Config::Model::Exception::User') ) { |
1574
|
|
|
|
|
|
|
if ( $check eq 'yes' ) { |
1575
|
435
|
100
|
|
|
|
1114
|
$e->rethrow; |
1576
|
41
|
|
50
|
|
|
154
|
} |
1577
|
41
|
|
|
|
|
186
|
$std_value = undef; |
1578
|
|
|
|
|
|
|
} |
1579
|
435
|
|
|
|
|
3180
|
elsif ( ref($e) ) { |
1580
|
|
|
|
|
|
|
$e->rethrow ; |
1581
|
0
|
|
|
|
|
0
|
} |
1582
|
|
|
|
|
|
|
elsif ($e) { |
1583
|
|
|
|
|
|
|
die $e; |
1584
|
|
|
|
|
|
|
} |
1585
|
80
|
|
|
80
|
1
|
838
|
|
1586
|
80
|
|
|
|
|
149
|
return $std_value; |
1587
|
|
|
|
|
|
|
} |
1588
|
|
|
|
|
|
|
|
1589
|
|
|
|
|
|
|
# use when std_value is needed to create error or warning message |
1590
|
9
|
|
|
9
|
1
|
699
|
# within a check sub. Using _fetch_std leads to deep recursions |
1591
|
9
|
|
|
|
|
1961
|
my ( $self, $check ) = @_; |
1592
|
|
|
|
|
|
|
|
1593
|
|
|
|
|
|
|
# get stored value or computed value or default value |
1594
|
|
|
|
|
|
|
my $std_value; |
1595
|
10
|
|
|
10
|
1
|
1598
|
|
1596
|
10
|
100
|
|
|
|
45
|
eval { |
1597
|
|
|
|
|
|
|
$std_value = |
1598
|
|
|
|
|
|
|
defined $self->{preset} ? $self->{preset} |
1599
|
|
|
|
|
|
|
: $self->compute_is_default ? $self->compute_obj->compute |
1600
|
3425
|
|
|
3425
|
|
5613
|
: $self->{default}; |
1601
|
|
|
|
|
|
|
}; |
1602
|
|
|
|
|
|
|
|
1603
|
|
|
|
|
|
|
if ($@) { |
1604
|
|
|
|
|
|
|
$logger->debug("eval got error: $@"); |
1605
|
|
|
|
|
|
|
} |
1606
|
|
|
|
|
|
|
|
1607
|
3425
|
100
|
100
|
|
|
13426
|
return $std_value; |
1608
|
55
|
|
|
|
|
204
|
} |
1609
|
55
|
|
|
|
|
242
|
|
1610
|
|
|
|
|
|
|
my %old_mode = ( |
1611
|
3423
|
|
|
|
|
5177
|
built_in => 'upstream_default', |
1612
|
|
|
|
|
|
|
non_built_in => 'non_upstream_default', |
1613
|
|
|
|
|
|
|
); |
1614
|
|
|
|
|
|
|
|
1615
|
|
|
|
|
|
|
{ |
1616
|
|
|
|
|
|
|
my %accept_mode = map { ( $_ => 1 ) } qw/custom standard preset default upstream_default |
1617
|
9460
|
|
|
9460
|
|
16802
|
layered non_upstream_default allow_undef user backend/; |
1618
|
|
|
|
|
|
|
|
1619
|
9460
|
50
|
33
|
|
|
20834
|
my ($self, $mode) = @_; |
1620
|
0
|
|
|
|
|
0
|
if ( $mode and not defined $accept_mode{$mode} ) { |
1621
|
|
|
|
|
|
|
my $good_ones = join( ' or ', sort keys %accept_mode ); |
1622
|
|
|
|
|
|
|
return "expected $good_ones as mode parameter, not $mode"; |
1623
|
|
|
|
|
|
|
} |
1624
|
9460
|
|
|
|
|
11690
|
} |
1625
|
|
|
|
|
|
|
} |
1626
|
9460
|
|
|
|
|
12914
|
|
1627
|
|
|
|
|
|
|
my ( $self, $mode, $check ) = @_; |
1628
|
|
|
|
|
|
|
$logger->trace( "called for " . $self->location ) if $logger->is_trace; |
1629
|
|
|
|
|
|
|
|
1630
|
9460
|
100
|
|
|
|
39937
|
# always call to perform submit_to_warp |
|
|
100
|
|
|
|
|
|
1631
|
|
|
|
|
|
|
my $pref = $self->_fetch_std( $check ); |
1632
|
|
|
|
|
|
|
|
1633
|
9460
|
|
|
|
|
14754
|
my $data = $self->{data}; |
1634
|
9460
|
100
|
66
|
|
|
27499
|
if ( defined $pref and not $self->{notified_change_for_default} and not defined $data ) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1635
|
4
|
100
|
|
|
|
18
|
$self->{notified_change_for_default} = 1; |
1636
|
2
|
|
|
|
|
11
|
my $info = defined $self->{preset} ? 'preset' |
1637
|
|
|
|
|
|
|
: $self->compute_is_default ? 'computed' |
1638
|
2
|
|
|
|
|
3
|
: 'default'; |
1639
|
|
|
|
|
|
|
$self->notify_change( old => undef, new => $pref, note => "use $info value" ); |
1640
|
|
|
|
|
|
|
} |
1641
|
0
|
|
|
|
|
0
|
|
1642
|
|
|
|
|
|
|
my $layer_data = $self->{layered}; |
1643
|
|
|
|
|
|
|
my $known_upstream = |
1644
|
0
|
|
|
|
|
0
|
defined $layer_data ? $layer_data |
1645
|
|
|
|
|
|
|
: $self->compute_is_upstream_default ? $self->perform_compute |
1646
|
|
|
|
|
|
|
: $self->{upstream_default}; |
1647
|
9458
|
|
|
|
|
16268
|
my $std = defined $pref ? $pref : $known_upstream; |
1648
|
|
|
|
|
|
|
|
1649
|
|
|
|
|
|
|
if ( defined $self->{_migrate_from} and not defined $data ) { |
1650
|
|
|
|
|
|
|
$data = $self->migrate_value; |
1651
|
|
|
|
|
|
|
} |
1652
|
|
|
|
|
|
|
|
1653
|
6
|
|
|
6
|
|
14
|
foreach my $k ( keys %old_mode ) { |
1654
|
|
|
|
|
|
|
next unless $mode eq $k; |
1655
|
|
|
|
|
|
|
$mode = $old_mode{$k}; |
1656
|
6
|
|
|
|
|
11
|
carp $self->location, " warning: deprecated mode parameter: $k, ", "expected $mode\n"; |
1657
|
|
|
|
|
|
|
} |
1658
|
6
|
|
|
|
|
11
|
|
1659
|
|
|
|
|
|
|
if (my $err = $self->is_bad_mode($mode)) { |
1660
|
|
|
|
|
|
|
croak "fetch_no_check: $err"; |
1661
|
|
|
|
|
|
|
} |
1662
|
6
|
50
|
|
|
|
33
|
|
|
|
50
|
|
|
|
|
|
1663
|
|
|
|
|
|
|
if ( $mode eq 'custom' ) { |
1664
|
|
|
|
|
|
|
## no critic (TestingAndDebugging::ProhibitNoWarning) |
1665
|
6
|
50
|
|
|
|
18
|
no warnings "uninitialized"; |
1666
|
0
|
|
|
|
|
0
|
my $cust; |
1667
|
|
|
|
|
|
|
$cust = $data |
1668
|
|
|
|
|
|
|
if $data ne $pref |
1669
|
6
|
|
|
|
|
12
|
and $data ne $self->{upstream_default} |
1670
|
|
|
|
|
|
|
and $data ne $layer_data; |
1671
|
|
|
|
|
|
|
$logger->debug( "custom mode result '$cust' for " . $self->location ) |
1672
|
|
|
|
|
|
|
if $logger->is_debug; |
1673
|
|
|
|
|
|
|
return $cust; |
1674
|
|
|
|
|
|
|
} |
1675
|
|
|
|
|
|
|
|
1676
|
|
|
|
|
|
|
if ( $mode eq 'non_upstream_default' ) { |
1677
|
|
|
|
|
|
|
## no critic (TestingAndDebugging::ProhibitNoWarning) |
1678
|
|
|
|
|
|
|
no warnings "uninitialized"; |
1679
|
|
|
|
|
|
|
my $nbu; |
1680
|
|
|
|
|
|
|
foreach my $d ($data, $layer_data, $pref) { |
1681
|
|
|
|
|
|
|
if ( defined $d and $d ne $self->{upstream_default} ) { |
1682
|
16108
|
|
|
16108
|
1
|
25292
|
$nbu = $d; |
1683
|
16108
|
50
|
33
|
|
|
65362
|
last; |
1684
|
0
|
|
|
|
|
0
|
} |
1685
|
0
|
|
|
|
|
0
|
} |
1686
|
|
|
|
|
|
|
|
1687
|
|
|
|
|
|
|
$logger->debug( "done in non_upstream_default mode for " . $self->location ) |
1688
|
|
|
|
|
|
|
if $logger->is_debug; |
1689
|
|
|
|
|
|
|
return $nbu; |
1690
|
|
|
|
|
|
|
} |
1691
|
7979
|
|
|
7979
|
|
13825
|
|
1692
|
7979
|
100
|
|
|
|
13995
|
my $res; |
1693
|
|
|
|
|
|
|
given ($mode) { |
1694
|
|
|
|
|
|
|
when ([qw/preset default upstream_default layered/]) { |
1695
|
7979
|
|
|
|
|
38188
|
$res = $self->{$mode}; |
1696
|
|
|
|
|
|
|
} |
1697
|
7977
|
|
|
|
|
13809
|
when ('standard') { |
1698
|
7977
|
100
|
100
|
|
|
18917
|
$res = $std; |
|
|
|
100
|
|
|
|
|
1699
|
170
|
|
|
|
|
450
|
} |
1700
|
170
|
100
|
|
|
|
752
|
when ('backend') { |
|
|
100
|
|
|
|
|
|
1701
|
|
|
|
|
|
|
$res = $self->_data_or_alt($data, $pref); |
1702
|
|
|
|
|
|
|
} |
1703
|
170
|
|
|
|
|
870
|
when ([qw/user allow_undef/]) { |
1704
|
|
|
|
|
|
|
$res = $self->_data_or_alt($data, $std); |
1705
|
|
|
|
|
|
|
} |
1706
|
7977
|
|
|
|
|
11695
|
default { |
1707
|
|
|
|
|
|
|
die "unexpected mode $mode "; |
1708
|
|
|
|
|
|
|
} |
1709
|
|
|
|
|
|
|
} |
1710
|
7977
|
100
|
|
|
|
26252
|
|
|
|
100
|
|
|
|
|
|
1711
|
7977
|
100
|
|
|
|
13113
|
$logger->debug( "done in '$mode' mode for " . $self->location . " -> " . ( $res // '<undef>' ) ) |
1712
|
|
|
|
|
|
|
if $logger->is_debug; |
1713
|
7977
|
100
|
100
|
|
|
17415
|
|
1714
|
23
|
|
|
|
|
69
|
return $res; |
1715
|
|
|
|
|
|
|
} |
1716
|
|
|
|
|
|
|
|
1717
|
7977
|
|
|
|
|
18563
|
my $res; |
1718
|
15954
|
50
|
|
|
|
28260
|
given ($self->value_type) { |
1719
|
0
|
|
|
|
|
0
|
when ([qw/integer boolean number/]) { |
1720
|
0
|
|
|
|
|
0
|
$res = $data // $alt |
1721
|
|
|
|
|
|
|
} |
1722
|
|
|
|
|
|
|
default { |
1723
|
7977
|
50
|
|
|
|
16333
|
# empty string is considered as undef, but empty string is |
1724
|
0
|
|
|
|
|
0
|
# still returned if there's not defined alternative ($alt) |
1725
|
|
|
|
|
|
|
$res = length($data) ? $data : $alt // $data |
1726
|
|
|
|
|
|
|
} |
1727
|
7977
|
100
|
|
|
|
16529
|
} |
1728
|
|
|
|
|
|
|
return $res; |
1729
|
59
|
|
|
59
|
|
539
|
} |
|
59
|
|
|
|
|
158
|
|
|
59
|
|
|
|
|
5486
|
|
1730
|
3082
|
|
|
|
|
3612
|
|
1731
|
|
|
|
|
|
|
my $self = shift; |
1732
|
|
|
|
|
|
|
carp "fetch_no_check is deprecated. Use fetch (check => 'no')"; |
1733
|
|
|
|
|
|
|
return $self->fetch( check => 'no' ); |
1734
|
3082
|
100
|
100
|
|
|
9713
|
} |
|
|
|
100
|
|
|
|
|
1735
|
3082
|
50
|
|
|
|
6469
|
|
1736
|
|
|
|
|
|
|
# likewise but without any warp, etc related check |
1737
|
3082
|
|
|
|
|
16156
|
my $self = shift; |
1738
|
|
|
|
|
|
|
return |
1739
|
|
|
|
|
|
|
defined $self->{data} ? $self->{data} |
1740
|
4895
|
100
|
|
|
|
8509
|
: defined $self->{preset} ? $self->{preset} |
1741
|
|
|
|
|
|
|
: defined $self->{compute} ? $self->perform_compute |
1742
|
59
|
|
|
59
|
|
397
|
: defined $self->{_migrate_from} ? $self->migrate_value |
|
59
|
|
|
|
|
122
|
|
|
59
|
|
|
|
|
107734
|
|
1743
|
6
|
|
|
|
|
13
|
: $self->{default}; |
1744
|
6
|
|
|
|
|
17
|
} |
1745
|
9
|
100
|
66
|
|
|
43
|
|
1746
|
5
|
|
|
|
|
12
|
my $value = $self->fetch(@args) // '<undef>'; |
1747
|
5
|
|
|
|
|
11
|
$value =~ s/\n/ /g; |
1748
|
|
|
|
|
|
|
$value = substr( $value, 0, 15 ) . '...' if length($value) > 15; |
1749
|
|
|
|
|
|
|
return $value; |
1750
|
|
|
|
|
|
|
} |
1751
|
6
|
50
|
|
|
|
20
|
|
1752
|
|
|
|
|
|
|
my %args = @args > 1 ? @args : ( mode => $args[0] ); |
1753
|
6
|
|
|
|
|
41
|
my $mode = $args{mode} || 'backend'; |
1754
|
|
|
|
|
|
|
my $silent = $args{silent} || 0; |
1755
|
|
|
|
|
|
|
my $check = $self->_check_check( $args{check} ); |
1756
|
4889
|
|
|
|
|
5763
|
|
1757
|
4889
|
|
|
|
|
6490
|
if ( $logger->is_trace ) { |
1758
|
4889
|
|
|
|
|
17348
|
$logger->trace( "called for " |
1759
|
95
|
|
|
|
|
212
|
. $self->location |
1760
|
|
|
|
|
|
|
. " check $check mode $mode" |
1761
|
4794
|
|
|
|
|
9449
|
. " needs_check " |
1762
|
50
|
|
|
|
|
105
|
. $self->needs_check ); |
1763
|
|
|
|
|
|
|
} |
1764
|
4744
|
|
|
|
|
7155
|
|
1765
|
2748
|
|
|
|
|
5240
|
my $inst = $self->instance; |
1766
|
|
|
|
|
|
|
|
1767
|
1996
|
|
|
|
|
3668
|
my $value = $self->_fetch( $mode, $check ); |
1768
|
1996
|
|
|
|
|
4109
|
|
1769
|
|
|
|
|
|
|
if ( $logger->is_debug ) { |
1770
|
0
|
|
|
|
|
0
|
$logger->debug( "_fetch returns " . ( defined $value ? $value : '<undef>' ) ); |
1771
|
0
|
|
|
|
|
0
|
} |
1772
|
|
|
|
|
|
|
|
1773
|
|
|
|
|
|
|
if ( my $err = $self->is_bad_mode($mode) ) { |
1774
|
|
|
|
|
|
|
croak "fetch: $err"; |
1775
|
4889
|
100
|
100
|
|
|
12189
|
} |
1776
|
|
|
|
|
|
|
|
1777
|
|
|
|
|
|
|
if ( defined $self->{replace_follow} and defined $value ) { |
1778
|
4889
|
|
|
|
|
28193
|
my $rep = $self->grab_value( |
1779
|
|
|
|
|
|
|
step => $self->{replace_follow} . qq!:"$value"!, |
1780
|
|
|
|
|
|
|
mode => 'loose', |
1781
|
4744
|
|
|
4744
|
|
5730
|
autoadd => 0, |
|
4744
|
|
|
|
|
6319
|
|
|
4744
|
|
|
|
|
6142
|
|
|
4744
|
|
|
|
|
5674
|
|
|
4744
|
|
|
|
|
5279
|
|
1782
|
4744
|
|
|
|
|
5662
|
); |
1783
|
4744
|
|
|
|
|
11351
|
|
1784
|
4744
|
|
|
|
|
11257
|
# store replaced value to trigger notify_change |
1785
|
1019
|
|
100
|
|
|
3616
|
if ( defined $rep and $rep ne $value ) { |
1786
|
|
|
|
|
|
|
$logger->debug( "fetch replace_follow $value with $rep from ".$self->{replace_follow}); |
1787
|
3725
|
|
|
|
|
6291
|
$value = $self->_store_value($rep); |
1788
|
|
|
|
|
|
|
} |
1789
|
|
|
|
|
|
|
} |
1790
|
3725
|
100
|
66
|
|
|
12728
|
|
1791
|
|
|
|
|
|
|
# check and subsequent storage of fixes instruction must be done only |
1792
|
|
|
|
|
|
|
# in user or custom mode. (because fixes are cleaned up during check and using |
1793
|
4744
|
|
|
|
|
10534
|
# mode may not trigger the warnings. Hence confusion afterwards) |
1794
|
|
|
|
|
|
|
my $ok = 1; |
1795
|
|
|
|
|
|
|
$ok = $self->check( value => $value, silent => $silent, mode => $mode ) |
1796
|
|
|
|
|
|
|
if $mode =~ /backend|custom|user/ and $check ne 'no'; |
1797
|
0
|
|
|
0
|
0
|
0
|
|
1798
|
0
|
|
|
|
|
0
|
$logger->trace( "$mode fetch (almost) done for " . $self->location ) |
1799
|
0
|
|
|
|
|
0
|
if $logger->is_trace; |
1800
|
|
|
|
|
|
|
|
1801
|
|
|
|
|
|
|
# check validity (all modes) |
1802
|
|
|
|
|
|
|
if ( $ok or $check eq 'no' ) { |
1803
|
|
|
|
|
|
|
return $self->map_write_as($value); |
1804
|
2159
|
|
|
2159
|
|
3652
|
} |
1805
|
|
|
|
|
|
|
elsif ( $check eq 'skip' ) { |
1806
|
|
|
|
|
|
|
my $msg = $self->error_msg; |
1807
|
|
|
|
|
|
|
my $str = $value // '<undef>'; |
1808
|
|
|
|
|
|
|
$user_logger->warn("Warning: fetch [".$self->name,"] skipping value $str because of the following errors:\n$msg\n") |
1809
|
|
|
|
|
|
|
if not $silent and $msg; |
1810
|
2159
|
100
|
|
|
|
9433
|
# this method is supposed to return a scalar |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1811
|
|
|
|
|
|
|
return undef; ## no critic(Subroutines::ProhibitExplicitReturnUndef) |
1812
|
|
|
|
|
|
|
|
1813
|
18
|
|
|
18
|
1
|
44
|
} |
|
18
|
|
|
|
|
25
|
|
|
18
|
|
|
|
|
43
|
|
|
18
|
|
|
|
|
34
|
|
1814
|
18
|
|
100
|
|
|
55
|
|
1815
|
18
|
|
|
|
|
65
|
Config::Model::Exception::WrongValue->throw( |
1816
|
18
|
100
|
|
|
|
56
|
object => $self, |
1817
|
18
|
|
|
|
|
109
|
error => $self->error_msg |
1818
|
|
|
|
|
|
|
); |
1819
|
|
|
|
|
|
|
|
1820
|
7979
|
|
|
7979
|
1
|
34763
|
return; |
|
7979
|
|
|
|
|
9810
|
|
|
7979
|
|
|
|
|
12438
|
|
|
7979
|
|
|
|
|
9458
|
|
1821
|
7979
|
100
|
|
|
|
22427
|
} |
1822
|
7979
|
|
100
|
|
|
20480
|
|
1823
|
7979
|
|
100
|
|
|
20418
|
my @res; |
1824
|
7979
|
|
|
|
|
19571
|
if ($self->{write_as} and $self->value_type eq 'boolean') { |
1825
|
|
|
|
|
|
|
foreach my $v (@args) { |
1826
|
7979
|
100
|
|
|
|
21596
|
push @res, ( defined $v and $v =~ /^\d+$/ ) ? $self->{write_as}[$v] : $v; |
1827
|
69
|
|
|
|
|
487
|
} |
1828
|
|
|
|
|
|
|
} |
1829
|
|
|
|
|
|
|
else { |
1830
|
|
|
|
|
|
|
@res = @args; |
1831
|
|
|
|
|
|
|
} |
1832
|
|
|
|
|
|
|
return wantarray ? @res : $res[0]; |
1833
|
|
|
|
|
|
|
} |
1834
|
7979
|
|
|
|
|
49847
|
|
1835
|
|
|
|
|
|
|
return shift->{data}; |
1836
|
7979
|
|
|
|
|
17069
|
} |
1837
|
|
|
|
|
|
|
|
1838
|
7977
|
100
|
|
|
|
14332
|
my $self = shift; |
1839
|
69
|
100
|
|
|
|
340
|
return $self->map_write_as( $self->{preset} ); |
1840
|
|
|
|
|
|
|
} |
1841
|
|
|
|
|
|
|
|
1842
|
7977
|
50
|
|
|
|
35707
|
my $self = shift; |
1843
|
0
|
|
|
|
|
0
|
$self->store(undef); |
1844
|
|
|
|
|
|
|
return; |
1845
|
|
|
|
|
|
|
} |
1846
|
7977
|
100
|
66
|
|
|
17546
|
|
1847
|
|
|
|
|
|
|
my $self = shift; |
1848
|
4
|
|
|
|
|
26
|
delete $self->{preset}; |
1849
|
|
|
|
|
|
|
return defined $self->{layered} || defined $self->{data}; |
1850
|
|
|
|
|
|
|
} |
1851
|
|
|
|
|
|
|
|
1852
|
|
|
|
|
|
|
my $self = shift; |
1853
|
|
|
|
|
|
|
return $self->map_write_as( $self->{layered} ); |
1854
|
4
|
100
|
66
|
|
|
15
|
} |
1855
|
2
|
|
|
|
|
9
|
|
1856
|
2
|
|
|
|
|
14
|
my $self = shift; |
1857
|
|
|
|
|
|
|
delete $self->{layered}; |
1858
|
|
|
|
|
|
|
return defined $self->{preset} || defined $self->{data}; |
1859
|
|
|
|
|
|
|
} |
1860
|
|
|
|
|
|
|
|
1861
|
|
|
|
|
|
|
my %args = @args > 1 ? @args : ( path => $args[0] ); |
1862
|
|
|
|
|
|
|
my $path = delete $args{path}; |
1863
|
7977
|
|
|
|
|
10921
|
if ($path) { |
1864
|
7977
|
100
|
100
|
|
|
53060
|
Config::Model::Exception::User->throw( |
1865
|
|
|
|
|
|
|
object => $self, |
1866
|
|
|
|
|
|
|
message => "get() called with a value with non-empty path: '$path'" |
1867
|
7977
|
100
|
|
|
|
55691
|
); |
1868
|
|
|
|
|
|
|
} |
1869
|
|
|
|
|
|
|
return $self->fetch(%args); |
1870
|
|
|
|
|
|
|
} |
1871
|
7977
|
100
|
66
|
|
|
43916
|
|
|
|
100
|
|
|
|
|
|
1872
|
7958
|
|
|
|
|
15411
|
if ($path) { |
1873
|
|
|
|
|
|
|
Config::Model::Exception::User->throw( |
1874
|
|
|
|
|
|
|
object => $self, |
1875
|
1
|
|
|
|
|
4
|
message => "set() called with a value with non-empty path: '$path'" |
1876
|
1
|
|
50
|
|
|
6
|
); |
1877
|
1
|
50
|
33
|
|
|
11
|
} |
1878
|
|
|
|
|
|
|
return $self->store(@data); |
1879
|
|
|
|
|
|
|
} |
1880
|
1
|
|
|
|
|
15
|
|
1881
|
|
|
|
|
|
|
#These methods are important when this leaf value is used as a warp |
1882
|
|
|
|
|
|
|
#master, or a variable in a compute formula. |
1883
|
|
|
|
|
|
|
|
1884
|
|
|
|
|
|
|
# register a dependency, This information may be used by external |
1885
|
18
|
|
|
|
|
91
|
# tools |
1886
|
|
|
|
|
|
|
my $self = shift; |
1887
|
|
|
|
|
|
|
my $slave = shift; |
1888
|
|
|
|
|
|
|
|
1889
|
0
|
|
|
|
|
0
|
unshift @{ $self->{depend_on_me} }, $slave; |
1890
|
|
|
|
|
|
|
|
1891
|
|
|
|
|
|
|
# weaken only applies to the passed reference, and there's no way |
1892
|
10441
|
|
|
10441
|
0
|
12484
|
# to duplicate a weak ref. Only a strong ref is created. |
|
10441
|
|
|
|
|
12072
|
|
|
10441
|
|
|
|
|
14555
|
|
|
10441
|
|
|
|
|
11360
|
|
1893
|
10441
|
|
|
|
|
12670
|
weaken( $self->{depend_on_me}[0] ); |
1894
|
10441
|
100
|
66
|
|
|
24053
|
return; |
1895
|
71
|
|
|
|
|
153
|
} |
1896
|
73
|
100
|
100
|
|
|
443
|
|
1897
|
|
|
|
|
|
|
my $self = shift; |
1898
|
|
|
|
|
|
|
|
1899
|
|
|
|
|
|
|
my @result = (); |
1900
|
10370
|
|
|
|
|
17132
|
push @result, @{ $self->{depend_on_me} } |
1901
|
|
|
|
|
|
|
if defined $self->{depend_on_me}; |
1902
|
10441
|
100
|
|
|
|
41072
|
|
1903
|
|
|
|
|
|
|
push @result, $self->get_warped_slaves; |
1904
|
|
|
|
|
|
|
|
1905
|
|
|
|
|
|
|
# needs to clean up weak ref to object that were destroyed |
1906
|
0
|
|
|
0
|
1
|
0
|
return grep { defined $_ } @result; |
1907
|
|
|
|
|
|
|
} |
1908
|
|
|
|
|
|
|
|
1909
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable; |
1910
|
0
|
|
|
0
|
1
|
0
|
|
1911
|
0
|
|
|
|
|
0
|
1; |
1912
|
|
|
|
|
|
|
|
1913
|
|
|
|
|
|
|
# ABSTRACT: Strongly typed configuration value |
1914
|
|
|
|
|
|
|
|
1915
|
3
|
|
|
3
|
1
|
811
|
|
1916
|
3
|
|
|
|
|
15
|
=pod |
1917
|
3
|
|
|
|
|
6
|
|
1918
|
|
|
|
|
|
|
=encoding UTF-8 |
1919
|
|
|
|
|
|
|
|
1920
|
|
|
|
|
|
|
=head1 NAME |
1921
|
32
|
|
|
32
|
1
|
40
|
|
1922
|
32
|
|
|
|
|
42
|
Config::Model::Value - Strongly typed configuration value |
1923
|
32
|
|
66
|
|
|
163
|
|
1924
|
|
|
|
|
|
|
=head1 VERSION |
1925
|
|
|
|
|
|
|
|
1926
|
|
|
|
|
|
|
version 2.152 |
1927
|
0
|
|
|
0
|
1
|
0
|
|
1928
|
0
|
|
|
|
|
0
|
=head1 SYNOPSIS |
1929
|
|
|
|
|
|
|
|
1930
|
|
|
|
|
|
|
use Config::Model; |
1931
|
|
|
|
|
|
|
|
1932
|
115
|
|
|
115
|
1
|
157
|
# define configuration tree object |
1933
|
115
|
|
|
|
|
175
|
my $model = Config::Model->new; |
1934
|
115
|
|
66
|
|
|
672
|
$model ->create_config_class ( |
1935
|
|
|
|
|
|
|
name => "MyClass", |
1936
|
|
|
|
|
|
|
|
1937
|
2
|
|
|
2
|
1
|
4
|
element => [ |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
3
|
|
1938
|
2
|
50
|
|
|
|
7
|
|
1939
|
2
|
|
|
|
|
4
|
[qw/foo bar/] => { |
1940
|
2
|
50
|
|
|
|
4
|
type => 'leaf', |
1941
|
0
|
|
|
|
|
0
|
value_type => 'string', |
1942
|
|
|
|
|
|
|
description => 'foobar', |
1943
|
|
|
|
|
|
|
} |
1944
|
|
|
|
|
|
|
, |
1945
|
|
|
|
|
|
|
country => { |
1946
|
2
|
|
|
|
|
7
|
type => 'leaf', |
1947
|
|
|
|
|
|
|
value_type => 'enum', |
1948
|
|
|
|
|
|
|
choice => [qw/France US/], |
1949
|
1
|
|
|
1
|
1
|
1
|
description => 'big countries', |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
2
|
|
1950
|
1
|
50
|
|
|
|
2
|
} |
1951
|
0
|
|
|
|
|
0
|
, |
1952
|
|
|
|
|
|
|
], |
1953
|
|
|
|
|
|
|
) ; |
1954
|
|
|
|
|
|
|
|
1955
|
|
|
|
|
|
|
my $inst = $model->instance(root_class_name => 'MyClass' ); |
1956
|
1
|
|
|
|
|
3
|
|
1957
|
|
|
|
|
|
|
my $root = $inst->config_root ; |
1958
|
|
|
|
|
|
|
|
1959
|
|
|
|
|
|
|
# put data |
1960
|
|
|
|
|
|
|
$root->load( steps => 'foo=FOO country=US' ); |
1961
|
|
|
|
|
|
|
|
1962
|
|
|
|
|
|
|
print $root->report ; |
1963
|
|
|
|
|
|
|
# foo = FOO |
1964
|
|
|
|
|
|
|
# DESCRIPTION: foobar |
1965
|
43
|
|
|
43
|
0
|
75
|
# |
1966
|
43
|
|
|
|
|
63
|
# country = US |
1967
|
|
|
|
|
|
|
# DESCRIPTION: big countries |
1968
|
43
|
|
|
|
|
59
|
|
|
43
|
|
|
|
|
127
|
|
1969
|
|
|
|
|
|
|
=head1 DESCRIPTION |
1970
|
|
|
|
|
|
|
|
1971
|
|
|
|
|
|
|
This class provides a way to specify configuration value with the |
1972
|
43
|
|
|
|
|
187
|
following properties: |
1973
|
43
|
|
|
|
|
81
|
|
1974
|
|
|
|
|
|
|
=over |
1975
|
|
|
|
|
|
|
|
1976
|
|
|
|
|
|
|
=item * |
1977
|
1242
|
|
|
1242
|
0
|
2398
|
|
1978
|
|
|
|
|
|
|
Strongly typed scalar: the value can either be an enumerated type, a boolean, |
1979
|
1242
|
|
|
|
|
2138
|
a number, an integer or a string |
1980
|
17
|
|
|
|
|
38
|
|
1981
|
1242
|
100
|
|
|
|
3338
|
=item * |
1982
|
|
|
|
|
|
|
|
1983
|
1242
|
|
|
|
|
4390
|
default parameter: a value can have a default value specified during |
1984
|
|
|
|
|
|
|
the construction. This default value is written in the target |
1985
|
|
|
|
|
|
|
configuration file. (C<default> parameter) |
1986
|
1242
|
|
|
|
|
11075
|
|
|
325
|
|
|
|
|
615
|
|
1987
|
|
|
|
|
|
|
=item * |
1988
|
|
|
|
|
|
|
|
1989
|
|
|
|
|
|
|
upstream default parameter: specifies a default value that is |
1990
|
|
|
|
|
|
|
used by the application when no information is provided in the |
1991
|
|
|
|
|
|
|
configuration file. This upstream_default value is not written in |
1992
|
|
|
|
|
|
|
the configuration files. Only the C<fetch_standard> method returns |
1993
|
|
|
|
|
|
|
the builtin value. This parameter was previously referred as |
1994
|
|
|
|
|
|
|
C<built_in> value. This may be used for audit |
1995
|
|
|
|
|
|
|
purpose. (C<upstream_default> parameter) |
1996
|
|
|
|
|
|
|
|
1997
|
|
|
|
|
|
|
=item * |
1998
|
|
|
|
|
|
|
|
1999
|
|
|
|
|
|
|
mandatory value: reading a mandatory value raises an exception if the |
2000
|
|
|
|
|
|
|
value is not specified (i.e is C<undef> or empty string) and has no |
2001
|
|
|
|
|
|
|
default value. |
2002
|
|
|
|
|
|
|
|
2003
|
|
|
|
|
|
|
=item * |
2004
|
|
|
|
|
|
|
|
2005
|
|
|
|
|
|
|
dynamic change of property: A slave value can be registered to another |
2006
|
|
|
|
|
|
|
master value so that the properties of the slave value can change |
2007
|
|
|
|
|
|
|
according to the value of the master value. For instance, paper size value |
2008
|
|
|
|
|
|
|
can be 'letter' for country 'US' and 'A4' for country 'France'. |
2009
|
|
|
|
|
|
|
|
2010
|
|
|
|
|
|
|
=item * |
2011
|
|
|
|
|
|
|
|
2012
|
|
|
|
|
|
|
A reference to the Id of a hash of list element. In other word, the |
2013
|
|
|
|
|
|
|
value is an enumerated type where the possible values (choice) is |
2014
|
|
|
|
|
|
|
defined by the existing keys of a has element somewhere in the tree. See |
2015
|
|
|
|
|
|
|
L</"Value Reference">. |
2016
|
|
|
|
|
|
|
|
2017
|
|
|
|
|
|
|
=back |
2018
|
|
|
|
|
|
|
|
2019
|
|
|
|
|
|
|
=head1 Default values |
2020
|
|
|
|
|
|
|
|
2021
|
|
|
|
|
|
|
There are several kind of default values. They depend on where these |
2022
|
|
|
|
|
|
|
values are defined (or found). |
2023
|
|
|
|
|
|
|
|
2024
|
|
|
|
|
|
|
From the lowest default level to the "highest": |
2025
|
|
|
|
|
|
|
|
2026
|
|
|
|
|
|
|
=over |
2027
|
|
|
|
|
|
|
|
2028
|
|
|
|
|
|
|
=item * |
2029
|
|
|
|
|
|
|
|
2030
|
|
|
|
|
|
|
C<upstream_default>: The value is known in the application, but is not |
2031
|
|
|
|
|
|
|
written in the configuration file. |
2032
|
|
|
|
|
|
|
|
2033
|
|
|
|
|
|
|
=item * |
2034
|
|
|
|
|
|
|
|
2035
|
|
|
|
|
|
|
C<layered>: The value is known by the application through another |
2036
|
|
|
|
|
|
|
mean (e.g. an included configuration file), but is not written in the |
2037
|
|
|
|
|
|
|
configuration file. |
2038
|
|
|
|
|
|
|
|
2039
|
|
|
|
|
|
|
=item * |
2040
|
|
|
|
|
|
|
|
2041
|
|
|
|
|
|
|
C<default>: The value is known by the model, but not by the |
2042
|
|
|
|
|
|
|
application. This value must be written in the configuration file. |
2043
|
|
|
|
|
|
|
|
2044
|
|
|
|
|
|
|
=item * |
2045
|
|
|
|
|
|
|
|
2046
|
|
|
|
|
|
|
C<computed>: The value is computed from other configuration |
2047
|
|
|
|
|
|
|
elements. This value must be written in the configuration file. |
2048
|
|
|
|
|
|
|
|
2049
|
|
|
|
|
|
|
=item * |
2050
|
|
|
|
|
|
|
|
2051
|
|
|
|
|
|
|
C<preset>: The value is not known by the model or by the |
2052
|
|
|
|
|
|
|
application. But it can be found by an automatic program and stored |
2053
|
|
|
|
|
|
|
while the configuration L<Config::Model::Instance|instance> is in |
2054
|
|
|
|
|
|
|
L<preset mode|Config::Model::Instance/"preset_start ()"> |
2055
|
|
|
|
|
|
|
|
2056
|
|
|
|
|
|
|
=back |
2057
|
|
|
|
|
|
|
|
2058
|
|
|
|
|
|
|
Then there is the value entered by the user. This overrides all |
2059
|
|
|
|
|
|
|
kind of "default" value. |
2060
|
|
|
|
|
|
|
|
2061
|
|
|
|
|
|
|
The L<fetch_standard> function returns the "highest" level of |
2062
|
|
|
|
|
|
|
default value, but does not return a custom value, i.e. a value |
2063
|
|
|
|
|
|
|
entered by the user. |
2064
|
|
|
|
|
|
|
|
2065
|
|
|
|
|
|
|
=head1 Constructor |
2066
|
|
|
|
|
|
|
|
2067
|
|
|
|
|
|
|
Value object should not be created directly. |
2068
|
|
|
|
|
|
|
|
2069
|
|
|
|
|
|
|
=head1 Value model declaration |
2070
|
|
|
|
|
|
|
|
2071
|
|
|
|
|
|
|
A leaf element must be declared with the following parameters: |
2072
|
|
|
|
|
|
|
|
2073
|
|
|
|
|
|
|
=over |
2074
|
|
|
|
|
|
|
|
2075
|
|
|
|
|
|
|
=item value_type |
2076
|
|
|
|
|
|
|
|
2077
|
|
|
|
|
|
|
Either C<boolean>, C<enum>, C<integer>, C<number>, |
2078
|
|
|
|
|
|
|
C<uniline>, C<string>, C<file>, C<dir>. Mandatory. See L</"Value types">. |
2079
|
|
|
|
|
|
|
|
2080
|
|
|
|
|
|
|
=item default |
2081
|
|
|
|
|
|
|
|
2082
|
|
|
|
|
|
|
Specify the default value (optional) |
2083
|
|
|
|
|
|
|
|
2084
|
|
|
|
|
|
|
=item upstream_default |
2085
|
|
|
|
|
|
|
|
2086
|
|
|
|
|
|
|
Specify a built in default value (optional). I.e a value known by the application |
2087
|
|
|
|
|
|
|
which does not need to be written in the configuration file. |
2088
|
|
|
|
|
|
|
|
2089
|
|
|
|
|
|
|
=item write_as |
2090
|
|
|
|
|
|
|
|
2091
|
|
|
|
|
|
|
Array ref. Reserved for boolean value. Specify how to write a boolean value. |
2092
|
|
|
|
|
|
|
Default is C<[0,1]> which may not be the most readable. C<write_as> can be |
2093
|
|
|
|
|
|
|
specified as C<['false','true']> or C<['no','yes']>. |
2094
|
|
|
|
|
|
|
|
2095
|
|
|
|
|
|
|
=item compute |
2096
|
|
|
|
|
|
|
|
2097
|
|
|
|
|
|
|
Computes a value according to a formula and other values. By default |
2098
|
|
|
|
|
|
|
a computed value cannot be set. See L<Config::Model::ValueComputer> for |
2099
|
|
|
|
|
|
|
computed value declaration. |
2100
|
|
|
|
|
|
|
|
2101
|
|
|
|
|
|
|
=item migrate_from |
2102
|
|
|
|
|
|
|
|
2103
|
|
|
|
|
|
|
This is a special parameter to cater for smooth configuration |
2104
|
|
|
|
|
|
|
upgrade. This parameter can be used to copy the value of a deprecated |
2105
|
|
|
|
|
|
|
parameter to its replacement. See L</Upgrade> for details. |
2106
|
|
|
|
|
|
|
|
2107
|
|
|
|
|
|
|
=item convert => [uc | lc ] |
2108
|
|
|
|
|
|
|
|
2109
|
|
|
|
|
|
|
When stored, the value is converted to uppercase (uc) or |
2110
|
|
|
|
|
|
|
lowercase (lc). |
2111
|
|
|
|
|
|
|
|
2112
|
|
|
|
|
|
|
=item min |
2113
|
|
|
|
|
|
|
|
2114
|
|
|
|
|
|
|
Specify the minimum value (optional, only for integer, number) |
2115
|
|
|
|
|
|
|
|
2116
|
|
|
|
|
|
|
=item max |
2117
|
|
|
|
|
|
|
|
2118
|
|
|
|
|
|
|
Specify the maximum value (optional, only for integer, number) |
2119
|
|
|
|
|
|
|
|
2120
|
|
|
|
|
|
|
=item mandatory |
2121
|
|
|
|
|
|
|
|
2122
|
|
|
|
|
|
|
Set to 1 if the configuration value B<must> be set by the |
2123
|
|
|
|
|
|
|
configuration user (default: 0) |
2124
|
|
|
|
|
|
|
|
2125
|
|
|
|
|
|
|
=item choice |
2126
|
|
|
|
|
|
|
|
2127
|
|
|
|
|
|
|
Array ref of the possible value of an enum. Example : |
2128
|
|
|
|
|
|
|
|
2129
|
|
|
|
|
|
|
choice => [ qw/foo bar/] |
2130
|
|
|
|
|
|
|
|
2131
|
|
|
|
|
|
|
=item match |
2132
|
|
|
|
|
|
|
|
2133
|
|
|
|
|
|
|
Perl regular expression. The value is matched with the regex to |
2134
|
|
|
|
|
|
|
assert its validity. Example C<< match => '^foo' >> means that the |
2135
|
|
|
|
|
|
|
parameter value must begin with "foo". Valid only for C<string> or |
2136
|
|
|
|
|
|
|
C<uniline> values. |
2137
|
|
|
|
|
|
|
|
2138
|
|
|
|
|
|
|
=item warn_if_match |
2139
|
|
|
|
|
|
|
|
2140
|
|
|
|
|
|
|
Hash ref. Keys are made of Perl regular expression. The value can |
2141
|
|
|
|
|
|
|
specify a warning message (leave empty or undefined for a default warning |
2142
|
|
|
|
|
|
|
message) and instructions to fix the value. A warning is issued |
2143
|
|
|
|
|
|
|
when the value matches the passed regular expression. Valid only for |
2144
|
|
|
|
|
|
|
C<string> or C<uniline> values. The fix instructions is evaluated |
2145
|
|
|
|
|
|
|
when L<apply_fixes> is called. C<$_> contains the value to fix. |
2146
|
|
|
|
|
|
|
C<$_> is stored as the new value once the instructions are done. |
2147
|
|
|
|
|
|
|
C<$self> contains the value object. Use with care. |
2148
|
|
|
|
|
|
|
|
2149
|
|
|
|
|
|
|
In the example below, any value matching 'foo' is converted in uppercase: |
2150
|
|
|
|
|
|
|
|
2151
|
|
|
|
|
|
|
warn_if_match => { |
2152
|
|
|
|
|
|
|
'foo' => { |
2153
|
|
|
|
|
|
|
fix => 'uc;', |
2154
|
|
|
|
|
|
|
msg => 'value $_ contains foo' |
2155
|
|
|
|
|
|
|
}, |
2156
|
|
|
|
|
|
|
'BAR' => { |
2157
|
|
|
|
|
|
|
fix =>'lc;', |
2158
|
|
|
|
|
|
|
msg => 'value $_ contains BAR' |
2159
|
|
|
|
|
|
|
} |
2160
|
|
|
|
|
|
|
}, |
2161
|
|
|
|
|
|
|
|
2162
|
|
|
|
|
|
|
The tests are done in alphabetical order. In the example above, C<BAR> test is |
2163
|
|
|
|
|
|
|
done before C<foo> test. |
2164
|
|
|
|
|
|
|
|
2165
|
|
|
|
|
|
|
C<$_> is substituted with the bad value when the message is generated. C<$std_value> |
2166
|
|
|
|
|
|
|
is substituted with the standard value (i.e the preset, computed or default value). |
2167
|
|
|
|
|
|
|
|
2168
|
|
|
|
|
|
|
=item warn_unless_match |
2169
|
|
|
|
|
|
|
|
2170
|
|
|
|
|
|
|
Hash ref like above. A warning is issued when the value does not |
2171
|
|
|
|
|
|
|
match the passed regular expression. Valid only for C<string> or |
2172
|
|
|
|
|
|
|
C<uniline> values. |
2173
|
|
|
|
|
|
|
|
2174
|
|
|
|
|
|
|
=item warn |
2175
|
|
|
|
|
|
|
|
2176
|
|
|
|
|
|
|
String. Issue a warning to user with the specified string any time a value is set or read. |
2177
|
|
|
|
|
|
|
|
2178
|
|
|
|
|
|
|
=item warn_if |
2179
|
|
|
|
|
|
|
|
2180
|
|
|
|
|
|
|
A bit like C<warn_if_match>. The hash key is not a regexp but a label to |
2181
|
|
|
|
|
|
|
help users. The hash ref contains some Perl code that is evaluated to |
2182
|
|
|
|
|
|
|
perform the test. A warning is issued if the given code returns true. |
2183
|
|
|
|
|
|
|
|
2184
|
|
|
|
|
|
|
C<$_> contains the value to check. C<$self> contains the |
2185
|
|
|
|
|
|
|
C<Config::Model::Value> object (use with care). |
2186
|
|
|
|
|
|
|
|
2187
|
|
|
|
|
|
|
The example below warns if value contains a number: |
2188
|
|
|
|
|
|
|
|
2189
|
|
|
|
|
|
|
warn_if => { |
2190
|
|
|
|
|
|
|
warn_test => { |
2191
|
|
|
|
|
|
|
code => 'defined $_ && /\d/;', |
2192
|
|
|
|
|
|
|
msg => 'value $_ should not have numbers', |
2193
|
|
|
|
|
|
|
fix => 's/\d//g;' |
2194
|
|
|
|
|
|
|
} |
2195
|
|
|
|
|
|
|
}, |
2196
|
|
|
|
|
|
|
|
2197
|
|
|
|
|
|
|
Hash key is used in warning message when C<msg> is not set: |
2198
|
|
|
|
|
|
|
|
2199
|
|
|
|
|
|
|
warn_if => { |
2200
|
|
|
|
|
|
|
'should begin with foo' => { |
2201
|
|
|
|
|
|
|
code => 'defined && /^foo/' |
2202
|
|
|
|
|
|
|
} |
2203
|
|
|
|
|
|
|
} |
2204
|
|
|
|
|
|
|
|
2205
|
|
|
|
|
|
|
Any operation or check on file must be done with C<file> sub |
2206
|
|
|
|
|
|
|
(otherwise tests will break). This sub returns a L<Path::Tiny> |
2207
|
|
|
|
|
|
|
object that can be used to perform checks. For instance: |
2208
|
|
|
|
|
|
|
|
2209
|
|
|
|
|
|
|
warn_if => { |
2210
|
|
|
|
|
|
|
warn_test => { |
2211
|
|
|
|
|
|
|
code => 'not file($_)->exists', |
2212
|
|
|
|
|
|
|
msg => 'file $_ should exist' |
2213
|
|
|
|
|
|
|
} |
2214
|
|
|
|
|
|
|
|
2215
|
|
|
|
|
|
|
=item warn_unless |
2216
|
|
|
|
|
|
|
|
2217
|
|
|
|
|
|
|
Like C<warn_if>, but issue a warning when the given C<code> returns false. |
2218
|
|
|
|
|
|
|
|
2219
|
|
|
|
|
|
|
The example below warns unless the value points to an existing directory: |
2220
|
|
|
|
|
|
|
|
2221
|
|
|
|
|
|
|
warn_unless => { |
2222
|
|
|
|
|
|
|
'missing dir' => { |
2223
|
|
|
|
|
|
|
code => '-d', |
2224
|
|
|
|
|
|
|
fix => "system(mkdir $_);" } |
2225
|
|
|
|
|
|
|
} |
2226
|
|
|
|
|
|
|
|
2227
|
|
|
|
|
|
|
=item assert |
2228
|
|
|
|
|
|
|
|
2229
|
|
|
|
|
|
|
Like C<warn_if>. Except that returned value triggers an error when the |
2230
|
|
|
|
|
|
|
given code returns false: |
2231
|
|
|
|
|
|
|
|
2232
|
|
|
|
|
|
|
assert => { |
2233
|
|
|
|
|
|
|
test_nb => { |
2234
|
|
|
|
|
|
|
code => 'defined $_ && /\d/;', |
2235
|
|
|
|
|
|
|
msg => 'should not have numbers', |
2236
|
|
|
|
|
|
|
fix => 's/\d//g;' |
2237
|
|
|
|
|
|
|
} |
2238
|
|
|
|
|
|
|
}, |
2239
|
|
|
|
|
|
|
|
2240
|
|
|
|
|
|
|
hash key can also be used to generate error message when C<msg> parameter is not set. |
2241
|
|
|
|
|
|
|
|
2242
|
|
|
|
|
|
|
=item grammar |
2243
|
|
|
|
|
|
|
|
2244
|
|
|
|
|
|
|
Setup a L<Parse::RecDescent> grammar to perform validation. |
2245
|
|
|
|
|
|
|
|
2246
|
|
|
|
|
|
|
If the grammar does not start with a "check" rule (i.e does not start with "check: "), |
2247
|
|
|
|
|
|
|
the first line of the grammar is modified to add "check" rule and this rules is set up so |
2248
|
|
|
|
|
|
|
the entire value must match the passed grammar. |
2249
|
|
|
|
|
|
|
|
2250
|
|
|
|
|
|
|
I.e. the grammar: |
2251
|
|
|
|
|
|
|
|
2252
|
|
|
|
|
|
|
token (oper token)(s?) |
2253
|
|
|
|
|
|
|
oper: 'and' | 'or' |
2254
|
|
|
|
|
|
|
token: 'Apache' | 'CC-BY' | 'Perl' |
2255
|
|
|
|
|
|
|
|
2256
|
|
|
|
|
|
|
is changed to |
2257
|
|
|
|
|
|
|
|
2258
|
|
|
|
|
|
|
check: token (oper token)(s?) /^\Z/ {$return = 1;} |
2259
|
|
|
|
|
|
|
oper: 'and' | 'or' |
2260
|
|
|
|
|
|
|
token: 'Apache' | 'CC-BY' | 'Perl' |
2261
|
|
|
|
|
|
|
|
2262
|
|
|
|
|
|
|
The rule is called with Value object and a string reference. So, in the |
2263
|
|
|
|
|
|
|
actions you may need to define, you can call the value object as |
2264
|
|
|
|
|
|
|
C<$arg[0]>, store error message in C<${$arg[1]}}> and store warnings in |
2265
|
|
|
|
|
|
|
C<${$arg[2]}}>. |
2266
|
|
|
|
|
|
|
|
2267
|
|
|
|
|
|
|
=item replace |
2268
|
|
|
|
|
|
|
|
2269
|
|
|
|
|
|
|
Hash ref. Used for enum to substitute one value with another. This |
2270
|
|
|
|
|
|
|
parameter must be used to enable user to upgrade a configuration with |
2271
|
|
|
|
|
|
|
obsolete values. For instance, if the value C<foo> is obsolete and |
2272
|
|
|
|
|
|
|
replaced by C<foo_better>, you must declare: |
2273
|
|
|
|
|
|
|
|
2274
|
|
|
|
|
|
|
replace => { foo => 'foo_better' } |
2275
|
|
|
|
|
|
|
|
2276
|
|
|
|
|
|
|
The hash key can also be a regular expression for wider range replacement. |
2277
|
|
|
|
|
|
|
The regexp must match the whole value: |
2278
|
|
|
|
|
|
|
|
2279
|
|
|
|
|
|
|
replace => ( 'foo.*' => 'better_foo' } |
2280
|
|
|
|
|
|
|
|
2281
|
|
|
|
|
|
|
In this case, a value is replaced by C<better_foo> when the |
2282
|
|
|
|
|
|
|
C</^foo.*$/> regexp matches. |
2283
|
|
|
|
|
|
|
|
2284
|
|
|
|
|
|
|
=item replace_follow |
2285
|
|
|
|
|
|
|
|
2286
|
|
|
|
|
|
|
Path specifying a hash of value element in the configuration tree. The |
2287
|
|
|
|
|
|
|
hash if used in a way similar to the C<replace> parameter. In this case, the |
2288
|
|
|
|
|
|
|
replacement is not coded in the model but specified by the configuration. |
2289
|
|
|
|
|
|
|
|
2290
|
|
|
|
|
|
|
=item refer_to |
2291
|
|
|
|
|
|
|
|
2292
|
|
|
|
|
|
|
Specify a path to an id element used as a reference. See L<Value |
2293
|
|
|
|
|
|
|
Reference> for details. |
2294
|
|
|
|
|
|
|
|
2295
|
|
|
|
|
|
|
=item computed_refer_to |
2296
|
|
|
|
|
|
|
|
2297
|
|
|
|
|
|
|
Specify a path to an id element used as a computed reference. See |
2298
|
|
|
|
|
|
|
L<Value Reference> for details. |
2299
|
|
|
|
|
|
|
|
2300
|
|
|
|
|
|
|
=item warp |
2301
|
|
|
|
|
|
|
|
2302
|
|
|
|
|
|
|
See section below: L</"Warp: dynamic value configuration">. |
2303
|
|
|
|
|
|
|
|
2304
|
|
|
|
|
|
|
=item help |
2305
|
|
|
|
|
|
|
|
2306
|
|
|
|
|
|
|
You may provide detailed description on possible values with a hash |
2307
|
|
|
|
|
|
|
ref. Example: |
2308
|
|
|
|
|
|
|
|
2309
|
|
|
|
|
|
|
help => { oui => "French for 'yes'", non => "French for 'no'"} |
2310
|
|
|
|
|
|
|
|
2311
|
|
|
|
|
|
|
The key of help is used as a regular expression to find the help text |
2312
|
|
|
|
|
|
|
applicable to a value. These regexp are tried from the longest to the |
2313
|
|
|
|
|
|
|
shortest and are matched from the beginning of the string. The key "C<.>" |
2314
|
|
|
|
|
|
|
or "C<.*>" are fallback used last. |
2315
|
|
|
|
|
|
|
|
2316
|
|
|
|
|
|
|
For instance: |
2317
|
|
|
|
|
|
|
|
2318
|
|
|
|
|
|
|
help => { |
2319
|
|
|
|
|
|
|
'foobar' => 'help for values matching /^foobar/', |
2320
|
|
|
|
|
|
|
'foo' => 'help for values matching /^foo/ but not /^foobar/ (used above)', |
2321
|
|
|
|
|
|
|
'.' => 'help for all other values' |
2322
|
|
|
|
|
|
|
} |
2323
|
|
|
|
|
|
|
|
2324
|
|
|
|
|
|
|
=back |
2325
|
|
|
|
|
|
|
|
2326
|
|
|
|
|
|
|
=head2 Value types |
2327
|
|
|
|
|
|
|
|
2328
|
|
|
|
|
|
|
This modules can check several value types: |
2329
|
|
|
|
|
|
|
|
2330
|
|
|
|
|
|
|
=over |
2331
|
|
|
|
|
|
|
|
2332
|
|
|
|
|
|
|
=item C<boolean> |
2333
|
|
|
|
|
|
|
|
2334
|
|
|
|
|
|
|
Accepts values C<1> or C<0>, C<yes> or C<no>, C<true> or C<false>, and |
2335
|
|
|
|
|
|
|
empty string. The value read back is always C<1> or C<0>. |
2336
|
|
|
|
|
|
|
|
2337
|
|
|
|
|
|
|
=item C<enum> |
2338
|
|
|
|
|
|
|
|
2339
|
|
|
|
|
|
|
Enum choices must be specified by the C<choice> parameter. |
2340
|
|
|
|
|
|
|
|
2341
|
|
|
|
|
|
|
=item C<integer> |
2342
|
|
|
|
|
|
|
|
2343
|
|
|
|
|
|
|
Enable positive or negative integer |
2344
|
|
|
|
|
|
|
|
2345
|
|
|
|
|
|
|
=item C<number> |
2346
|
|
|
|
|
|
|
|
2347
|
|
|
|
|
|
|
The value can be a decimal number |
2348
|
|
|
|
|
|
|
|
2349
|
|
|
|
|
|
|
=item C<uniline> |
2350
|
|
|
|
|
|
|
|
2351
|
|
|
|
|
|
|
A one line string. I.e without "\n" in it. |
2352
|
|
|
|
|
|
|
|
2353
|
|
|
|
|
|
|
=item C<string> |
2354
|
|
|
|
|
|
|
|
2355
|
|
|
|
|
|
|
Actually, no check is performed with this type. |
2356
|
|
|
|
|
|
|
|
2357
|
|
|
|
|
|
|
=item C<reference> |
2358
|
|
|
|
|
|
|
|
2359
|
|
|
|
|
|
|
Like an C<enum> where the possible values (aka choice) is defined by |
2360
|
|
|
|
|
|
|
another location if the configuration tree. See L</Value Reference>. |
2361
|
|
|
|
|
|
|
|
2362
|
|
|
|
|
|
|
=item C<file> |
2363
|
|
|
|
|
|
|
|
2364
|
|
|
|
|
|
|
A file name or path. A warning is issued if the file does not |
2365
|
|
|
|
|
|
|
exists (or is a directory) |
2366
|
|
|
|
|
|
|
|
2367
|
|
|
|
|
|
|
=item C<dir> |
2368
|
|
|
|
|
|
|
|
2369
|
|
|
|
|
|
|
A directory name or path. A warning is issued if the directory |
2370
|
|
|
|
|
|
|
does not exists (or is a plain file) |
2371
|
|
|
|
|
|
|
|
2372
|
|
|
|
|
|
|
=back |
2373
|
|
|
|
|
|
|
|
2374
|
|
|
|
|
|
|
=head1 Warp: dynamic value configuration |
2375
|
|
|
|
|
|
|
|
2376
|
|
|
|
|
|
|
The Warp functionality enable a C<Value> object to change its |
2377
|
|
|
|
|
|
|
properties (i.e. default value or its type) dynamically according to |
2378
|
|
|
|
|
|
|
the value of another C<Value> object locate elsewhere in the |
2379
|
|
|
|
|
|
|
configuration tree. (See L<Config::Model::Warper> for an |
2380
|
|
|
|
|
|
|
explanation on warp mechanism). |
2381
|
|
|
|
|
|
|
|
2382
|
|
|
|
|
|
|
For instance if you declare 2 C<Value> element this way: |
2383
|
|
|
|
|
|
|
|
2384
|
|
|
|
|
|
|
$model ->create_config_class ( |
2385
|
|
|
|
|
|
|
name => "TV_config_class", |
2386
|
|
|
|
|
|
|
element => [ |
2387
|
|
|
|
|
|
|
country => { |
2388
|
|
|
|
|
|
|
type => 'leaf', |
2389
|
|
|
|
|
|
|
value_type => 'enum', |
2390
|
|
|
|
|
|
|
choice => [qw/US Europe Japan/] |
2391
|
|
|
|
|
|
|
} , |
2392
|
|
|
|
|
|
|
tv_standard => { # this example is getting old... |
2393
|
|
|
|
|
|
|
type => 'leaf', |
2394
|
|
|
|
|
|
|
value_type => 'enum', |
2395
|
|
|
|
|
|
|
choice => [ qw/PAL NTSC SECAM/ ] |
2396
|
|
|
|
|
|
|
warp => { |
2397
|
|
|
|
|
|
|
follow => { |
2398
|
|
|
|
|
|
|
# this points to the warp master |
2399
|
|
|
|
|
|
|
c => '- country' |
2400
|
|
|
|
|
|
|
}, |
2401
|
|
|
|
|
|
|
rules => { |
2402
|
|
|
|
|
|
|
'$c eq "US"' => { |
2403
|
|
|
|
|
|
|
default => 'NTSC' |
2404
|
|
|
|
|
|
|
}, |
2405
|
|
|
|
|
|
|
'$c eq "France"' => { |
2406
|
|
|
|
|
|
|
default => 'SECAM' |
2407
|
|
|
|
|
|
|
}, |
2408
|
|
|
|
|
|
|
'$c eq "Japan"' => { |
2409
|
|
|
|
|
|
|
default => 'NTSC' |
2410
|
|
|
|
|
|
|
}, |
2411
|
|
|
|
|
|
|
'$c eq "Europe"' => { |
2412
|
|
|
|
|
|
|
default => 'PAL' |
2413
|
|
|
|
|
|
|
}, |
2414
|
|
|
|
|
|
|
} |
2415
|
|
|
|
|
|
|
} |
2416
|
|
|
|
|
|
|
} , |
2417
|
|
|
|
|
|
|
] |
2418
|
|
|
|
|
|
|
); |
2419
|
|
|
|
|
|
|
|
2420
|
|
|
|
|
|
|
Setting C<country> element to C<US> means that C<tv_standard> has |
2421
|
|
|
|
|
|
|
a default value set to C<NTSC> by the warp mechanism. |
2422
|
|
|
|
|
|
|
|
2423
|
|
|
|
|
|
|
Likewise, the warp mechanism enables you to dynamically change the |
2424
|
|
|
|
|
|
|
possible values of an enum element: |
2425
|
|
|
|
|
|
|
|
2426
|
|
|
|
|
|
|
state => { |
2427
|
|
|
|
|
|
|
type => 'leaf', |
2428
|
|
|
|
|
|
|
value_type => 'enum', # example is admittedly silly |
2429
|
|
|
|
|
|
|
warp => { |
2430
|
|
|
|
|
|
|
follow => { |
2431
|
|
|
|
|
|
|
c => '- country' |
2432
|
|
|
|
|
|
|
}, |
2433
|
|
|
|
|
|
|
rules => { |
2434
|
|
|
|
|
|
|
'$c eq "US"' => { |
2435
|
|
|
|
|
|
|
choice => ['Kansas', 'Texas' ] |
2436
|
|
|
|
|
|
|
}, |
2437
|
|
|
|
|
|
|
'$c eq "Europe"' => { |
2438
|
|
|
|
|
|
|
choice => ['France', 'Spain' ] |
2439
|
|
|
|
|
|
|
}, |
2440
|
|
|
|
|
|
|
'$c eq "Japan"' => { |
2441
|
|
|
|
|
|
|
choice => ['Honshu', 'Hokkaido' ] |
2442
|
|
|
|
|
|
|
} |
2443
|
|
|
|
|
|
|
} |
2444
|
|
|
|
|
|
|
} |
2445
|
|
|
|
|
|
|
} |
2446
|
|
|
|
|
|
|
|
2447
|
|
|
|
|
|
|
=head2 Cascaded warping |
2448
|
|
|
|
|
|
|
|
2449
|
|
|
|
|
|
|
Warping value can be cascaded: C<A> can be warped by C<B> which can be |
2450
|
|
|
|
|
|
|
warped by C<C>. But this feature should be avoided since it can lead |
2451
|
|
|
|
|
|
|
to a model very hard to debug. Bear in mind that: |
2452
|
|
|
|
|
|
|
|
2453
|
|
|
|
|
|
|
=over |
2454
|
|
|
|
|
|
|
|
2455
|
|
|
|
|
|
|
=item * |
2456
|
|
|
|
|
|
|
|
2457
|
|
|
|
|
|
|
Warp loops are not detected and end up in "deep recursion |
2458
|
|
|
|
|
|
|
subroutine" failures. |
2459
|
|
|
|
|
|
|
|
2460
|
|
|
|
|
|
|
=item * |
2461
|
|
|
|
|
|
|
|
2462
|
|
|
|
|
|
|
avoid "diamond" shaped warp dependencies: the results depends on the |
2463
|
|
|
|
|
|
|
order of the warp algorithm which can be unpredictable in this case |
2464
|
|
|
|
|
|
|
|
2465
|
|
|
|
|
|
|
=item * |
2466
|
|
|
|
|
|
|
|
2467
|
|
|
|
|
|
|
The keys declared in the warp rules (C<US>, C<Europe> and C<Japan> in |
2468
|
|
|
|
|
|
|
the example above) cannot be checked at start time against the warp |
2469
|
|
|
|
|
|
|
master C<Value>. So a wrong warp rule key is silently ignored |
2470
|
|
|
|
|
|
|
during start up and fails at run time. |
2471
|
|
|
|
|
|
|
|
2472
|
|
|
|
|
|
|
=back |
2473
|
|
|
|
|
|
|
|
2474
|
|
|
|
|
|
|
=head1 Value Reference |
2475
|
|
|
|
|
|
|
|
2476
|
|
|
|
|
|
|
To set up an enumerated value where the possible choice depends on the |
2477
|
|
|
|
|
|
|
key of a L<Config::Model::AnyId> object, you must: |
2478
|
|
|
|
|
|
|
|
2479
|
|
|
|
|
|
|
=over |
2480
|
|
|
|
|
|
|
|
2481
|
|
|
|
|
|
|
=item * |
2482
|
|
|
|
|
|
|
|
2483
|
|
|
|
|
|
|
Set C<value_type> to C<reference>. |
2484
|
|
|
|
|
|
|
|
2485
|
|
|
|
|
|
|
=item * |
2486
|
|
|
|
|
|
|
|
2487
|
|
|
|
|
|
|
Specify the C<refer_to> or C<computed_refer_to> parameter. |
2488
|
|
|
|
|
|
|
See L<refer_to parameter|Config::Model::IdElementReference/"Config class parameters">. |
2489
|
|
|
|
|
|
|
|
2490
|
|
|
|
|
|
|
=back |
2491
|
|
|
|
|
|
|
|
2492
|
|
|
|
|
|
|
In this case, a C<IdElementReference> object is created to handle the |
2493
|
|
|
|
|
|
|
relation between this value object and the referred Id. See |
2494
|
|
|
|
|
|
|
L<Config::Model::IdElementReference> for details. |
2495
|
|
|
|
|
|
|
|
2496
|
|
|
|
|
|
|
=head1 Introspection methods |
2497
|
|
|
|
|
|
|
|
2498
|
|
|
|
|
|
|
The following methods returns the current value of the parameter of |
2499
|
|
|
|
|
|
|
the value object (as declared in the model unless they were warped): |
2500
|
|
|
|
|
|
|
|
2501
|
|
|
|
|
|
|
=over |
2502
|
|
|
|
|
|
|
|
2503
|
|
|
|
|
|
|
=item min |
2504
|
|
|
|
|
|
|
|
2505
|
|
|
|
|
|
|
=item max |
2506
|
|
|
|
|
|
|
|
2507
|
|
|
|
|
|
|
=item mandatory |
2508
|
|
|
|
|
|
|
|
2509
|
|
|
|
|
|
|
=item choice |
2510
|
|
|
|
|
|
|
|
2511
|
|
|
|
|
|
|
=item convert |
2512
|
|
|
|
|
|
|
|
2513
|
|
|
|
|
|
|
=item value_type |
2514
|
|
|
|
|
|
|
|
2515
|
|
|
|
|
|
|
=item default |
2516
|
|
|
|
|
|
|
|
2517
|
|
|
|
|
|
|
=item upstream_default |
2518
|
|
|
|
|
|
|
|
2519
|
|
|
|
|
|
|
=item index_value |
2520
|
|
|
|
|
|
|
|
2521
|
|
|
|
|
|
|
=item element_name |
2522
|
|
|
|
|
|
|
|
2523
|
|
|
|
|
|
|
=back |
2524
|
|
|
|
|
|
|
|
2525
|
|
|
|
|
|
|
=head2 name |
2526
|
|
|
|
|
|
|
|
2527
|
|
|
|
|
|
|
Returns the object name. |
2528
|
|
|
|
|
|
|
|
2529
|
|
|
|
|
|
|
=head2 get_type |
2530
|
|
|
|
|
|
|
|
2531
|
|
|
|
|
|
|
Returns C<leaf>. |
2532
|
|
|
|
|
|
|
|
2533
|
|
|
|
|
|
|
=head2 can_store |
2534
|
|
|
|
|
|
|
|
2535
|
|
|
|
|
|
|
Returns true if the value object can be assigned to. Return 0 for a |
2536
|
|
|
|
|
|
|
read-only value (i.e. a computed value with no override allowed). |
2537
|
|
|
|
|
|
|
|
2538
|
|
|
|
|
|
|
=head2 get_choice |
2539
|
|
|
|
|
|
|
|
2540
|
|
|
|
|
|
|
Query legal values (only for enum types). Return an array (possibly |
2541
|
|
|
|
|
|
|
empty). |
2542
|
|
|
|
|
|
|
|
2543
|
|
|
|
|
|
|
=head2 get_help |
2544
|
|
|
|
|
|
|
|
2545
|
|
|
|
|
|
|
With a parameter, returns the help string applicable to the passed |
2546
|
|
|
|
|
|
|
value or undef. |
2547
|
|
|
|
|
|
|
|
2548
|
|
|
|
|
|
|
Without parameter returns a hash ref that contains all the help strings. |
2549
|
|
|
|
|
|
|
|
2550
|
|
|
|
|
|
|
=head2 get_info |
2551
|
|
|
|
|
|
|
|
2552
|
|
|
|
|
|
|
Returns a list of information related to the value, like value type, |
2553
|
|
|
|
|
|
|
default value. This should be used to provide some debug information |
2554
|
|
|
|
|
|
|
to the user. |
2555
|
|
|
|
|
|
|
|
2556
|
|
|
|
|
|
|
For instance, C<$val->get-info> may return: |
2557
|
|
|
|
|
|
|
|
2558
|
|
|
|
|
|
|
[ 'type: string', 'mandatory: yes' ] |
2559
|
|
|
|
|
|
|
|
2560
|
|
|
|
|
|
|
=head2 error_msg |
2561
|
|
|
|
|
|
|
|
2562
|
|
|
|
|
|
|
Returns the error messages of this object (if any) |
2563
|
|
|
|
|
|
|
|
2564
|
|
|
|
|
|
|
=head2 warning_msg |
2565
|
|
|
|
|
|
|
|
2566
|
|
|
|
|
|
|
Returns warning concerning this value. Returns a list in list |
2567
|
|
|
|
|
|
|
context and a string in scalar context. |
2568
|
|
|
|
|
|
|
|
2569
|
|
|
|
|
|
|
=head2 check_value |
2570
|
|
|
|
|
|
|
|
2571
|
|
|
|
|
|
|
Parameters: C<< ( value ) >> |
2572
|
|
|
|
|
|
|
|
2573
|
|
|
|
|
|
|
Check the consistency of the value. |
2574
|
|
|
|
|
|
|
|
2575
|
|
|
|
|
|
|
C<check_value> also accepts named parameters: |
2576
|
|
|
|
|
|
|
|
2577
|
|
|
|
|
|
|
=over 4 |
2578
|
|
|
|
|
|
|
|
2579
|
|
|
|
|
|
|
=item value |
2580
|
|
|
|
|
|
|
|
2581
|
|
|
|
|
|
|
=item quiet |
2582
|
|
|
|
|
|
|
|
2583
|
|
|
|
|
|
|
When non null, check does not try to get extra |
2584
|
|
|
|
|
|
|
information from the tree. This is required in some cases to avoid |
2585
|
|
|
|
|
|
|
loops in check, get_info, get_warp_info, re-check ... |
2586
|
|
|
|
|
|
|
|
2587
|
|
|
|
|
|
|
=back |
2588
|
|
|
|
|
|
|
|
2589
|
|
|
|
|
|
|
In scalar context, return 0 or 1. |
2590
|
|
|
|
|
|
|
|
2591
|
|
|
|
|
|
|
In array context, return an empty array when no error was found. In |
2592
|
|
|
|
|
|
|
case of errors, returns an array of error strings that should be shown |
2593
|
|
|
|
|
|
|
to the user. |
2594
|
|
|
|
|
|
|
|
2595
|
|
|
|
|
|
|
=head2 has_fixes |
2596
|
|
|
|
|
|
|
|
2597
|
|
|
|
|
|
|
Returns the number of fixes that can be applied to the current value. |
2598
|
|
|
|
|
|
|
|
2599
|
|
|
|
|
|
|
=head2 apply_fixes |
2600
|
|
|
|
|
|
|
|
2601
|
|
|
|
|
|
|
Applies the fixes to suppress the current warnings. |
2602
|
|
|
|
|
|
|
|
2603
|
|
|
|
|
|
|
=head2 check |
2604
|
|
|
|
|
|
|
|
2605
|
|
|
|
|
|
|
Parameters: C<< ( [ value => foo ] ) >> |
2606
|
|
|
|
|
|
|
|
2607
|
|
|
|
|
|
|
Like L</check_value>. |
2608
|
|
|
|
|
|
|
|
2609
|
|
|
|
|
|
|
Also displays warnings on STDOUT unless C<silent> parameter is set to 1. |
2610
|
|
|
|
|
|
|
In this case,user is expected to retrieve them with |
2611
|
|
|
|
|
|
|
L</warning_msg>. |
2612
|
|
|
|
|
|
|
|
2613
|
|
|
|
|
|
|
Without C<value> argument, this method checks the value currently stored. |
2614
|
|
|
|
|
|
|
|
2615
|
|
|
|
|
|
|
=head2 is_bad_mode |
2616
|
|
|
|
|
|
|
|
2617
|
|
|
|
|
|
|
Accept a mode parameter. This function checks if the mode is accepted |
2618
|
|
|
|
|
|
|
by L</fetch> method. Returns an error message if not. For instance: |
2619
|
|
|
|
|
|
|
|
2620
|
|
|
|
|
|
|
if (my $err = $val->is_bad_mode('foo')) { |
2621
|
|
|
|
|
|
|
croak "my_function: $err"; |
2622
|
|
|
|
|
|
|
} |
2623
|
|
|
|
|
|
|
|
2624
|
|
|
|
|
|
|
This method is intented as a helper to avoid duplicating the list of |
2625
|
|
|
|
|
|
|
accepted modes for functions that want to wrap fetch methods (like |
2626
|
|
|
|
|
|
|
L<Config::Model::Dumper> or L<Config::Model::DumpAsData>) |
2627
|
|
|
|
|
|
|
|
2628
|
|
|
|
|
|
|
=head1 Information management |
2629
|
|
|
|
|
|
|
|
2630
|
|
|
|
|
|
|
=head2 store |
2631
|
|
|
|
|
|
|
|
2632
|
|
|
|
|
|
|
Parameters: C<< ( $value ) >> |
2633
|
|
|
|
|
|
|
or C<< value => ..., check => yes|no|skip ), silent => 0|1 >> |
2634
|
|
|
|
|
|
|
|
2635
|
|
|
|
|
|
|
Store value in leaf element. C<check> parameter can be used to |
2636
|
|
|
|
|
|
|
skip validation check (default is 'yes'). |
2637
|
|
|
|
|
|
|
C<silent> can be used to suppress warnings. |
2638
|
|
|
|
|
|
|
|
2639
|
|
|
|
|
|
|
Optional C<callback> is now deprecated. |
2640
|
|
|
|
|
|
|
|
2641
|
|
|
|
|
|
|
=head2 clear |
2642
|
|
|
|
|
|
|
|
2643
|
|
|
|
|
|
|
Clear the stored value. Further read returns the default value (or |
2644
|
|
|
|
|
|
|
computed or migrated value). |
2645
|
|
|
|
|
|
|
|
2646
|
|
|
|
|
|
|
=head2 load_data |
2647
|
|
|
|
|
|
|
|
2648
|
|
|
|
|
|
|
Parameters: C<< ( $value ) >> |
2649
|
|
|
|
|
|
|
|
2650
|
|
|
|
|
|
|
Called with the same parameters are C<store> method. |
2651
|
|
|
|
|
|
|
|
2652
|
|
|
|
|
|
|
Load scalar data. Data is forwarded to L</"store"> after checking that |
2653
|
|
|
|
|
|
|
the passed value is not a reference. |
2654
|
|
|
|
|
|
|
|
2655
|
|
|
|
|
|
|
=head2 fetch_custom |
2656
|
|
|
|
|
|
|
|
2657
|
|
|
|
|
|
|
Returns the stored value if this value is different from a standard |
2658
|
|
|
|
|
|
|
setting or built in setting. In other words, returns undef if the |
2659
|
|
|
|
|
|
|
stored value is identical to the default value or the computed value |
2660
|
|
|
|
|
|
|
or the built in value. |
2661
|
|
|
|
|
|
|
|
2662
|
|
|
|
|
|
|
=head2 fetch_standard |
2663
|
|
|
|
|
|
|
|
2664
|
|
|
|
|
|
|
Returns the standard value as defined by the configuration model. The |
2665
|
|
|
|
|
|
|
standard value can be either a preset value, a layered value, a computed value, a |
2666
|
|
|
|
|
|
|
default value or a built-in default value. |
2667
|
|
|
|
|
|
|
|
2668
|
|
|
|
|
|
|
=head2 has_data |
2669
|
|
|
|
|
|
|
|
2670
|
|
|
|
|
|
|
Return true if the value contains information different from default |
2671
|
|
|
|
|
|
|
or upstream default value. |
2672
|
|
|
|
|
|
|
|
2673
|
|
|
|
|
|
|
=head2 fetch |
2674
|
|
|
|
|
|
|
|
2675
|
|
|
|
|
|
|
Check and fetch value from leaf element. The method can have one parameter (the fetch mode) |
2676
|
|
|
|
|
|
|
or several pairs: |
2677
|
|
|
|
|
|
|
|
2678
|
|
|
|
|
|
|
=over 4 |
2679
|
|
|
|
|
|
|
|
2680
|
|
|
|
|
|
|
=item mode |
2681
|
|
|
|
|
|
|
|
2682
|
|
|
|
|
|
|
Whether to fetch default, custom, etc value. See below for details |
2683
|
|
|
|
|
|
|
|
2684
|
|
|
|
|
|
|
=item check |
2685
|
|
|
|
|
|
|
|
2686
|
|
|
|
|
|
|
Whether to check if the value is valid or not before returning it. Default is 'yes'. |
2687
|
|
|
|
|
|
|
Possible value are |
2688
|
|
|
|
|
|
|
|
2689
|
|
|
|
|
|
|
=over 4 |
2690
|
|
|
|
|
|
|
|
2691
|
|
|
|
|
|
|
=item yes |
2692
|
|
|
|
|
|
|
|
2693
|
|
|
|
|
|
|
Perform check and raise an exception for bad values |
2694
|
|
|
|
|
|
|
|
2695
|
|
|
|
|
|
|
=item skip |
2696
|
|
|
|
|
|
|
|
2697
|
|
|
|
|
|
|
Perform check and return undef for bad values. A warning is issued when a bad value is skipped. |
2698
|
|
|
|
|
|
|
Set C<check> to C<no> to avoid warnings. |
2699
|
|
|
|
|
|
|
|
2700
|
|
|
|
|
|
|
=item no |
2701
|
|
|
|
|
|
|
|
2702
|
|
|
|
|
|
|
Do not check and return values even if bad |
2703
|
|
|
|
|
|
|
|
2704
|
|
|
|
|
|
|
=back |
2705
|
|
|
|
|
|
|
|
2706
|
|
|
|
|
|
|
=item silent |
2707
|
|
|
|
|
|
|
|
2708
|
|
|
|
|
|
|
When set to 1, warning are not displayed on STDOUT. User is expected to read warnings |
2709
|
|
|
|
|
|
|
with L<warning_msg> method. |
2710
|
|
|
|
|
|
|
|
2711
|
|
|
|
|
|
|
=back |
2712
|
|
|
|
|
|
|
|
2713
|
|
|
|
|
|
|
According to the C<mode> parameter, this method returns either: |
2714
|
|
|
|
|
|
|
|
2715
|
|
|
|
|
|
|
=over |
2716
|
|
|
|
|
|
|
|
2717
|
|
|
|
|
|
|
=item empty mode parameter (default) |
2718
|
|
|
|
|
|
|
|
2719
|
|
|
|
|
|
|
Value entered by user or default value if the value is different from upstream_default or |
2720
|
|
|
|
|
|
|
layered value. Typically this value is written in a configuration file. |
2721
|
|
|
|
|
|
|
|
2722
|
|
|
|
|
|
|
=item backend |
2723
|
|
|
|
|
|
|
|
2724
|
|
|
|
|
|
|
Alias for default mode. |
2725
|
|
|
|
|
|
|
|
2726
|
|
|
|
|
|
|
=item custom |
2727
|
|
|
|
|
|
|
|
2728
|
|
|
|
|
|
|
The value entered by the user (if different from built in, preset, |
2729
|
|
|
|
|
|
|
computed or default value) |
2730
|
|
|
|
|
|
|
|
2731
|
|
|
|
|
|
|
=item user |
2732
|
|
|
|
|
|
|
|
2733
|
|
|
|
|
|
|
The value most useful to user: the value that is used by the application. |
2734
|
|
|
|
|
|
|
|
2735
|
|
|
|
|
|
|
=item preset |
2736
|
|
|
|
|
|
|
|
2737
|
|
|
|
|
|
|
The value entered in preset mode |
2738
|
|
|
|
|
|
|
|
2739
|
|
|
|
|
|
|
=item standard |
2740
|
|
|
|
|
|
|
|
2741
|
|
|
|
|
|
|
The preset or computed or default or built in value. |
2742
|
|
|
|
|
|
|
|
2743
|
|
|
|
|
|
|
=item default |
2744
|
|
|
|
|
|
|
|
2745
|
|
|
|
|
|
|
The default value (defined by the configuration model) |
2746
|
|
|
|
|
|
|
|
2747
|
|
|
|
|
|
|
=item layered |
2748
|
|
|
|
|
|
|
|
2749
|
|
|
|
|
|
|
The value found in included files (treated in layered mode: values specified |
2750
|
|
|
|
|
|
|
there are handled as upstream default values). E.g. like in multistrap config. |
2751
|
|
|
|
|
|
|
|
2752
|
|
|
|
|
|
|
=item upstream_default |
2753
|
|
|
|
|
|
|
|
2754
|
|
|
|
|
|
|
The upstream_default value. (defined by the configuration model) |
2755
|
|
|
|
|
|
|
|
2756
|
|
|
|
|
|
|
=item non_upstream_default |
2757
|
|
|
|
|
|
|
|
2758
|
|
|
|
|
|
|
The custom or preset or computed or default value. Returns undef |
2759
|
|
|
|
|
|
|
if either of this value is identical to the upstream_default value. This |
2760
|
|
|
|
|
|
|
feature is useful to reduce data to write in configuration file. |
2761
|
|
|
|
|
|
|
|
2762
|
|
|
|
|
|
|
=item allow_undef |
2763
|
|
|
|
|
|
|
|
2764
|
|
|
|
|
|
|
With this mode, C<fetch()> behaves like in C<user> mode, but returns |
2765
|
|
|
|
|
|
|
C<undef> for mandatory values. Normally, trying to fetch an undefined |
2766
|
|
|
|
|
|
|
mandatory value leads to an exception. |
2767
|
|
|
|
|
|
|
|
2768
|
|
|
|
|
|
|
=back |
2769
|
|
|
|
|
|
|
|
2770
|
|
|
|
|
|
|
=head2 fetch_summary |
2771
|
|
|
|
|
|
|
|
2772
|
|
|
|
|
|
|
Returns a truncated value when the value is a string or uniline that |
2773
|
|
|
|
|
|
|
is too long to be displayed. |
2774
|
|
|
|
|
|
|
|
2775
|
|
|
|
|
|
|
=head2 user_value |
2776
|
|
|
|
|
|
|
|
2777
|
|
|
|
|
|
|
Returns the value entered by the user. Does not use the default or |
2778
|
|
|
|
|
|
|
computed value. Returns undef unless a value was actually stored. |
2779
|
|
|
|
|
|
|
|
2780
|
|
|
|
|
|
|
=head2 fetch_preset |
2781
|
|
|
|
|
|
|
|
2782
|
|
|
|
|
|
|
Returns the value entered in preset mode. Does not use the default or |
2783
|
|
|
|
|
|
|
computed value. Returns undef unless a value was actually stored in |
2784
|
|
|
|
|
|
|
preset mode. |
2785
|
|
|
|
|
|
|
|
2786
|
|
|
|
|
|
|
=head2 clear_preset |
2787
|
|
|
|
|
|
|
|
2788
|
|
|
|
|
|
|
Delete the preset value. (Even out of preset mode). Returns true if other data |
2789
|
|
|
|
|
|
|
are still stored in the value (layered or user data). Returns false otherwise. |
2790
|
|
|
|
|
|
|
|
2791
|
|
|
|
|
|
|
=head2 fetch_layered |
2792
|
|
|
|
|
|
|
|
2793
|
|
|
|
|
|
|
Returns the value entered in layered mode. Does not use the default or |
2794
|
|
|
|
|
|
|
computed value. Returns undef unless a value was actually stored in |
2795
|
|
|
|
|
|
|
layered mode. |
2796
|
|
|
|
|
|
|
|
2797
|
|
|
|
|
|
|
=head2 clear_layered |
2798
|
|
|
|
|
|
|
|
2799
|
|
|
|
|
|
|
Delete the layered value. (Even out of layered mode). Returns true if other data |
2800
|
|
|
|
|
|
|
are still stored in the value (layered or user data). Returns false otherwise. |
2801
|
|
|
|
|
|
|
|
2802
|
|
|
|
|
|
|
=head2 get( path => ..., mode => ... , check => ... ) |
2803
|
|
|
|
|
|
|
|
2804
|
|
|
|
|
|
|
Get a value from a directory like path. |
2805
|
|
|
|
|
|
|
|
2806
|
|
|
|
|
|
|
=head2 set( path , value ) |
2807
|
|
|
|
|
|
|
|
2808
|
|
|
|
|
|
|
Set a value from a directory like path. |
2809
|
|
|
|
|
|
|
|
2810
|
|
|
|
|
|
|
=head1 Examples |
2811
|
|
|
|
|
|
|
|
2812
|
|
|
|
|
|
|
=head2 Number with min and max values |
2813
|
|
|
|
|
|
|
|
2814
|
|
|
|
|
|
|
bounded_number => { |
2815
|
|
|
|
|
|
|
type => 'leaf', |
2816
|
|
|
|
|
|
|
value_type => 'number', |
2817
|
|
|
|
|
|
|
min => 1, |
2818
|
|
|
|
|
|
|
max => 4, |
2819
|
|
|
|
|
|
|
}, |
2820
|
|
|
|
|
|
|
|
2821
|
|
|
|
|
|
|
=head2 Mandatory value |
2822
|
|
|
|
|
|
|
|
2823
|
|
|
|
|
|
|
mandatory_string => { |
2824
|
|
|
|
|
|
|
type => 'leaf', |
2825
|
|
|
|
|
|
|
value_type => 'string', |
2826
|
|
|
|
|
|
|
mandatory => 1, |
2827
|
|
|
|
|
|
|
}, |
2828
|
|
|
|
|
|
|
|
2829
|
|
|
|
|
|
|
mandatory_boolean => { |
2830
|
|
|
|
|
|
|
type => 'leaf', |
2831
|
|
|
|
|
|
|
value_type => 'boolean', |
2832
|
|
|
|
|
|
|
mandatory => 1, |
2833
|
|
|
|
|
|
|
}, |
2834
|
|
|
|
|
|
|
|
2835
|
|
|
|
|
|
|
=head2 Enum with help associated with each value |
2836
|
|
|
|
|
|
|
|
2837
|
|
|
|
|
|
|
Note that the help specification is optional. |
2838
|
|
|
|
|
|
|
|
2839
|
|
|
|
|
|
|
enum_with_help => { |
2840
|
|
|
|
|
|
|
type => 'leaf', |
2841
|
|
|
|
|
|
|
value_type => 'enum', |
2842
|
|
|
|
|
|
|
choice => [qw/a b c/], |
2843
|
|
|
|
|
|
|
help => { |
2844
|
|
|
|
|
|
|
a => 'a help' |
2845
|
|
|
|
|
|
|
} |
2846
|
|
|
|
|
|
|
}, |
2847
|
|
|
|
|
|
|
|
2848
|
|
|
|
|
|
|
=head2 Migrate old obsolete enum value |
2849
|
|
|
|
|
|
|
|
2850
|
|
|
|
|
|
|
Legacy values C<a1>, C<c1> and C<foo/.*> are replaced with C<a>, C<c> and C<foo/>. |
2851
|
|
|
|
|
|
|
|
2852
|
|
|
|
|
|
|
with_replace => { |
2853
|
|
|
|
|
|
|
type => 'leaf', |
2854
|
|
|
|
|
|
|
value_type => 'enum', |
2855
|
|
|
|
|
|
|
choice => [qw/a b c/], |
2856
|
|
|
|
|
|
|
replace => { |
2857
|
|
|
|
|
|
|
a1 => 'a', |
2858
|
|
|
|
|
|
|
c1 => 'c', |
2859
|
|
|
|
|
|
|
'foo/.*' => 'foo', |
2860
|
|
|
|
|
|
|
}, |
2861
|
|
|
|
|
|
|
}, |
2862
|
|
|
|
|
|
|
|
2863
|
|
|
|
|
|
|
=head2 Enforce value to match a regexp |
2864
|
|
|
|
|
|
|
|
2865
|
|
|
|
|
|
|
An exception is triggered when the value does not match the C<match> |
2866
|
|
|
|
|
|
|
regular expression. |
2867
|
|
|
|
|
|
|
|
2868
|
|
|
|
|
|
|
match => { |
2869
|
|
|
|
|
|
|
type => 'leaf', |
2870
|
|
|
|
|
|
|
value_type => 'string', |
2871
|
|
|
|
|
|
|
match => '^foo\d{2}$', |
2872
|
|
|
|
|
|
|
}, |
2873
|
|
|
|
|
|
|
|
2874
|
|
|
|
|
|
|
=head2 Enforce value to match a L<Parse::RecDescent> grammar |
2875
|
|
|
|
|
|
|
|
2876
|
|
|
|
|
|
|
match_with_parse_recdescent => { |
2877
|
|
|
|
|
|
|
type => 'leaf', |
2878
|
|
|
|
|
|
|
value_type => 'string', |
2879
|
|
|
|
|
|
|
grammar => q{ |
2880
|
|
|
|
|
|
|
token (oper token)(s?) |
2881
|
|
|
|
|
|
|
oper: 'and' | 'or' |
2882
|
|
|
|
|
|
|
token: 'Apache' | 'CC-BY' | 'Perl' |
2883
|
|
|
|
|
|
|
}, |
2884
|
|
|
|
|
|
|
}, |
2885
|
|
|
|
|
|
|
|
2886
|
|
|
|
|
|
|
=head2 Issue a warning if a value matches a regexp |
2887
|
|
|
|
|
|
|
|
2888
|
|
|
|
|
|
|
Issue a warning if the string contains upper case letters. Propose a fix that |
2889
|
|
|
|
|
|
|
translate all capital letters to lower case. |
2890
|
|
|
|
|
|
|
|
2891
|
|
|
|
|
|
|
warn_if_capital => { |
2892
|
|
|
|
|
|
|
type => 'leaf', |
2893
|
|
|
|
|
|
|
value_type => 'string', |
2894
|
|
|
|
|
|
|
warn_if_match => { |
2895
|
|
|
|
|
|
|
'/A-Z/' => { |
2896
|
|
|
|
|
|
|
fix => '$_ = lc;' |
2897
|
|
|
|
|
|
|
} |
2898
|
|
|
|
|
|
|
}, |
2899
|
|
|
|
|
|
|
}, |
2900
|
|
|
|
|
|
|
|
2901
|
|
|
|
|
|
|
A specific warning can be specified: |
2902
|
|
|
|
|
|
|
|
2903
|
|
|
|
|
|
|
warn_if_capital => { |
2904
|
|
|
|
|
|
|
type => 'leaf', |
2905
|
|
|
|
|
|
|
value_type => 'string', |
2906
|
|
|
|
|
|
|
warn_if_match => { |
2907
|
|
|
|
|
|
|
'/A-Z/' => { |
2908
|
|
|
|
|
|
|
fix => '$_ = lc;', |
2909
|
|
|
|
|
|
|
mesg => 'NO UPPER CASE PLEASE' |
2910
|
|
|
|
|
|
|
} |
2911
|
|
|
|
|
|
|
}, |
2912
|
|
|
|
|
|
|
}, |
2913
|
|
|
|
|
|
|
|
2914
|
|
|
|
|
|
|
=head2 Issue a warning if a value does NOT match a regexp |
2915
|
|
|
|
|
|
|
|
2916
|
|
|
|
|
|
|
warn_unless => { |
2917
|
|
|
|
|
|
|
type => 'leaf', |
2918
|
|
|
|
|
|
|
value_type => 'string', |
2919
|
|
|
|
|
|
|
warn_unless_match => { |
2920
|
|
|
|
|
|
|
foo => { |
2921
|
|
|
|
|
|
|
msg => '', |
2922
|
|
|
|
|
|
|
fix => '$_ = "foo".$_;' |
2923
|
|
|
|
|
|
|
} |
2924
|
|
|
|
|
|
|
}, |
2925
|
|
|
|
|
|
|
}, |
2926
|
|
|
|
|
|
|
|
2927
|
|
|
|
|
|
|
=head2 Always issue a warning |
2928
|
|
|
|
|
|
|
|
2929
|
|
|
|
|
|
|
always_warn => { |
2930
|
|
|
|
|
|
|
type => 'leaf', |
2931
|
|
|
|
|
|
|
value_type => 'string', |
2932
|
|
|
|
|
|
|
warn => 'Always warn whenever used', |
2933
|
|
|
|
|
|
|
}, |
2934
|
|
|
|
|
|
|
|
2935
|
|
|
|
|
|
|
=head2 Computed values |
2936
|
|
|
|
|
|
|
|
2937
|
|
|
|
|
|
|
See L<Config::Model::ValueComputer/Examples>. |
2938
|
|
|
|
|
|
|
|
2939
|
|
|
|
|
|
|
=head1 Upgrade |
2940
|
|
|
|
|
|
|
|
2941
|
|
|
|
|
|
|
Upgrade is a special case when the configuration of an application has |
2942
|
|
|
|
|
|
|
changed. Some parameters can be removed and replaced by another |
2943
|
|
|
|
|
|
|
one. To avoid trouble on the application user side, Config::Model |
2944
|
|
|
|
|
|
|
offers a possibility to handle the migration of configuration data |
2945
|
|
|
|
|
|
|
through a special declaration in the configuration model. |
2946
|
|
|
|
|
|
|
|
2947
|
|
|
|
|
|
|
This declaration must: |
2948
|
|
|
|
|
|
|
|
2949
|
|
|
|
|
|
|
=over |
2950
|
|
|
|
|
|
|
|
2951
|
|
|
|
|
|
|
=item * |
2952
|
|
|
|
|
|
|
|
2953
|
|
|
|
|
|
|
Declare the deprecated parameter with a C<status> set to C<deprecated> |
2954
|
|
|
|
|
|
|
|
2955
|
|
|
|
|
|
|
=item * |
2956
|
|
|
|
|
|
|
|
2957
|
|
|
|
|
|
|
Declare the new parameter with the instructions to load the semantic |
2958
|
|
|
|
|
|
|
content from the deprecated parameter. These instructions are declared |
2959
|
|
|
|
|
|
|
in the C<migrate_from> parameters (which is similar to the C<compute> |
2960
|
|
|
|
|
|
|
parameter) |
2961
|
|
|
|
|
|
|
|
2962
|
|
|
|
|
|
|
=back |
2963
|
|
|
|
|
|
|
|
2964
|
|
|
|
|
|
|
Here an example where a URL parameter is changed to a set of 2 |
2965
|
|
|
|
|
|
|
parameters (host and path): |
2966
|
|
|
|
|
|
|
|
2967
|
|
|
|
|
|
|
'old_url' => { |
2968
|
|
|
|
|
|
|
type => 'leaf', |
2969
|
|
|
|
|
|
|
value_type => 'uniline', |
2970
|
|
|
|
|
|
|
status => 'deprecated', |
2971
|
|
|
|
|
|
|
}, |
2972
|
|
|
|
|
|
|
'host' => { |
2973
|
|
|
|
|
|
|
type => 'leaf', |
2974
|
|
|
|
|
|
|
value_type => 'uniline', |
2975
|
|
|
|
|
|
|
|
2976
|
|
|
|
|
|
|
# the formula must end with '$1' so the result of the capture is used |
2977
|
|
|
|
|
|
|
# as the host value |
2978
|
|
|
|
|
|
|
migrate_from => { |
2979
|
|
|
|
|
|
|
formula => '$old =~ m!http://([\w\.]+)!; $1 ;', |
2980
|
|
|
|
|
|
|
variables => { |
2981
|
|
|
|
|
|
|
old => '- old_url' |
2982
|
|
|
|
|
|
|
}, |
2983
|
|
|
|
|
|
|
use_eval => 1, |
2984
|
|
|
|
|
|
|
}, |
2985
|
|
|
|
|
|
|
}, |
2986
|
|
|
|
|
|
|
'path' => { |
2987
|
|
|
|
|
|
|
type => 'leaf', |
2988
|
|
|
|
|
|
|
value_type => 'uniline', |
2989
|
|
|
|
|
|
|
migrate_from => { |
2990
|
|
|
|
|
|
|
formula => '$old =~ m!http://[\w\.]+(/.*)!; $1 ;', |
2991
|
|
|
|
|
|
|
variables => { |
2992
|
|
|
|
|
|
|
old => '- old_url' |
2993
|
|
|
|
|
|
|
}, |
2994
|
|
|
|
|
|
|
use_eval => 1, |
2995
|
|
|
|
|
|
|
}, |
2996
|
|
|
|
|
|
|
}, |
2997
|
|
|
|
|
|
|
|
2998
|
|
|
|
|
|
|
=head1 EXCEPTION HANDLING |
2999
|
|
|
|
|
|
|
|
3000
|
|
|
|
|
|
|
When an error is encountered, this module may throw the following |
3001
|
|
|
|
|
|
|
exceptions: |
3002
|
|
|
|
|
|
|
|
3003
|
|
|
|
|
|
|
Config::Model::Exception::Model |
3004
|
|
|
|
|
|
|
Config::Model::Exception::Formula |
3005
|
|
|
|
|
|
|
Config::Model::Exception::WrongValue |
3006
|
|
|
|
|
|
|
Config::Model::Exception::WarpError |
3007
|
|
|
|
|
|
|
|
3008
|
|
|
|
|
|
|
See L<Config::Model::Exception> for more details. |
3009
|
|
|
|
|
|
|
|
3010
|
|
|
|
|
|
|
=head1 AUTHOR |
3011
|
|
|
|
|
|
|
|
3012
|
|
|
|
|
|
|
Dominique Dumont, (ddumont at cpan dot org) |
3013
|
|
|
|
|
|
|
|
3014
|
|
|
|
|
|
|
=head1 SEE ALSO |
3015
|
|
|
|
|
|
|
|
3016
|
|
|
|
|
|
|
L<Config::Model>, L<Config::Model::Node>, |
3017
|
|
|
|
|
|
|
L<Config::Model::AnyId>, L<Config::Model::Warper>, L<Config::Model::Exception> |
3018
|
|
|
|
|
|
|
L<Config::Model::ValueComputer>, |
3019
|
|
|
|
|
|
|
|
3020
|
|
|
|
|
|
|
=head1 AUTHOR |
3021
|
|
|
|
|
|
|
|
3022
|
|
|
|
|
|
|
Dominique Dumont |
3023
|
|
|
|
|
|
|
|
3024
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
3025
|
|
|
|
|
|
|
|
3026
|
|
|
|
|
|
|
This software is Copyright (c) 2005-2022 by Dominique Dumont. |
3027
|
|
|
|
|
|
|
|
3028
|
|
|
|
|
|
|
This is free software, licensed under: |
3029
|
|
|
|
|
|
|
|
3030
|
|
|
|
|
|
|
The GNU Lesser General Public License, Version 2.1, February 1999 |
3031
|
|
|
|
|
|
|
|
3032
|
|
|
|
|
|
|
=cut |