File Coverage

blib/lib/Config/Model/Value.pm
Criterion Covered Total %
statement 873 947 92.1
branch 441 548 80.4
condition 278 365 76.1
subroutine 106 115 92.1
pod 29 64 45.3
total 1727 2039 84.7


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