File Coverage

blib/lib/Config/Model/Value.pm
Criterion Covered Total %
statement 870 944 92.1
branch 439 546 80.4
condition 278 365 76.1
subroutine 106 115 92.1
pod 29 64 45.3
total 1722 2034 84.6


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