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