--- trunk/lib/WebPAC/Validate.pm 2006/09/06 19:52:36 640 +++ trunk/lib/WebPAC/Validate.pm 2006/09/06 23:13:03 647 @@ -9,6 +9,8 @@ use File::Slurp; use List::Util qw/first/; use Data::Dumper; +use WebPAC::Normalize qw/_pack_subfields_hash/; +use Storable qw/dclone/; =head1 NAME @@ -16,11 +18,11 @@ =head1 VERSION -Version 0.01 +Version 0.04 =cut -our $VERSION = '0.01'; +our $VERSION = '0.04'; =head1 SYNOPSIS @@ -32,9 +34,11 @@ # same with 101 101 # field 200 have valid subfields a-g - 200 a b c d e f g + # and field e is repeatable + 200 a b c d e* f g # field 205 can have only subfield a - 205 a + # and must exists + 205! a # while 210 can have a c or d 210 a c d @@ -45,7 +49,7 @@ Create new validation object my $validate = new WebPAC::Validate( - path => '/path/to/input/validate_file', + path => 'conf/validate/file', ); =cut @@ -80,10 +84,20 @@ my $fld = shift @d; + if ($fld =~ s/!$//) { + $self->{must_exist}->{$fld}++; + } + $log->logdie("need field name in line $curr_line: $l") unless (defined($fld)); if (@d) { - $v->{$fld} = \@d; + $v->{$fld} = [ map { + my $sf = $_; + if ( $sf =~ s/!(\*)?$/$1/ ) { + $self->{must_exist_sf}->{ $fld }->{ $sf }++; + }; + $sf; + } @d ]; } else { $v->{$fld} = 1; } @@ -121,15 +135,20 @@ $log->debug("rec = ", sub { Dumper($rec) }, "keys = ", keys %{ $rec }); + my $fields; + foreach my $f (keys %{ $rec }) { next if (!defined($f) || $f eq '' || $f eq '000'); - if (! defined($r->{$f})) { + $fields->{$f}++; + + if ( ! defined($r->{$f}) ) { push @errors, "field '$f' shouldn't exists"; next; } + if (ref($rec->{$f}) ne 'ARRAY') { push @errors, "field '$f' isn't repetable, probably bug in parsing input data"; next; @@ -143,12 +162,51 @@ push @errors, "$f has value without subfields: $v"; next; } else { + + my $h = dclone( $v ); + + my $sf_repeatable; + + delete($v->{subfields}) if (defined($v->{subfields})); + + my $subfields; + foreach my $sf (keys %{ $v }) { - # permited subfield? - if (! first { $_ eq $sf } @{ $r->{$f} }) { - push @errors, "$f has unknown subfield: $sf" if ($sf ne 'subfields'); + + $subfields->{ $sf }++; + + # is non-repeatable but with multiple values? + if ( ! first { $_ eq $sf.'*' } @{$r->{$f}} ) { + if ( ref($v->{$sf}) eq 'ARRAY' ) { + $sf_repeatable->{$sf}++; + }; + if (! first { $_ eq $sf } @{ $r->{$f} }) { + push @errors, "$f has unknown subfield: $sf"; + } + } + + } + if (my @r_sf = sort keys( %$sf_repeatable )) { + my $plural = $#r_sf > 0 ? 1 : 0; + + push @errors, "$f subfield" . + ( $plural ? 's ' : ' ' ) . + join(', ', @r_sf) . + ( $plural ? ' are ' : ' is ' ) . + 'repeatable in: ' . + join('', _pack_subfields_hash( $h, 1) ); + } + + if ( defined( $self->{must_exist_sf}->{$f} ) ) { + foreach my $sf (sort keys %{ $self->{must_exist_sf}->{$f} }) { +#warn "====> $f $sf must exist\n"; + push @errors, "$f missing required subfield $sf" + unless ( + defined( $subfields->{$sf} ) + ) } } + } } elsif (ref($v) eq 'HASH') { push @errors, "$f has subfields which is not valid"; @@ -156,6 +214,12 @@ } } + foreach my $must (sort keys %{ $self->{must_exist} }) { + next if ($fields->{$must}); + push @errors, + "field $must should exist, but it doesn't"; + } + #$log->logcluck("return from this function is ARRAY") unless wantarray; $log->debug("errors: ", join(", ", @errors)) if (@errors);