r1650@llin: dpavlin | 2007-11-20 11:07:57 +0100
[webpac2] / lib / WebPAC / Validate.pm
index a5e6b19..d7ed6fb 100644 (file)
@@ -60,6 +60,9 @@ Optional parametar C<delimiters> will turn on validating of delimiters. Be
 careful here, those delimiters are just stuck into regex, so they can
 contain L<perlre> regexpes.
 
+C<path> and C<delimiters_path> can be specified by L<read_validate_file> and
+L<read_validate_delimiters> calls.
+
 =cut
 
 sub new {
@@ -69,84 +72,123 @@ sub new {
 
        my $log = $self->_get_logger();
 
-       $log->logdie("need path or delimiters_path") unless ( $self->{path} || $self->{delimiters_path} );
+       $self->read_validate_file( $self->{path} ) if ( $self->{path} );
 
-       if ( $self->{path} ) {
+       if ( $self->{delimiters} ) {
+               $self->{delimiters_regex} = '(\^[a-z0-9]|' . join('|', @{ $self->{delimiters} }) . ')';
+               $log->info("validation check delimiters with regex $self->{delimiters_regex}");
+       }
 
-               my $v_file = read_file( $self->{path} ) ||
-                       $log->logdie("can't open validate path $self->{path}: $!");
+       $self->read_validate_delimiters_file( $self->{delimiters_path} ) if ( $self->{delimiters_path} );
 
-               my $v;
-               my $curr_line = 1;
+       return $self;
+}
 
-               foreach my $l (split(/[\n\r]+/, $v_file)) {
-                       $curr_line++;
 
-                       # skip comments and whitespaces
-                       next if ($l =~ /^#/ || $l =~ /^\s*$/);
+=head2 read_validate_file
 
-                       $l =~ s/^\s+//;
-                       $l =~ s/\s+$//;
+Specify validate rules file
 
-                       my @d = split(/\s+/, $l);
+  $validate->read_validate_file( 'conf/validate/file' );
 
-                       my $fld = shift @d;
+Returns number of lines in file
 
-                       if ($fld =~ s/!$//) {
-                               $self->{must_exist}->{$fld}++;
-                       } elsif ($fld =~ s/-$//) {
-                               $self->{dont_validate}->{$fld}++;
-                       }
+=cut
 
-                       $log->logdie("need field name in line $curr_line: $l") unless (defined($fld));
+sub read_validate_file {
+       my $self = shift;
 
-                       if (@d) {
-                               $v->{$fld} = [ map {
-                                       my $sf = $_;
-                                       if ( $sf =~ s/!(\*)?$/$1/ ) {
-                                               $self->{must_exist_sf}->{ $fld }->{ $sf }++;
-                                       };
-                                       $sf;
-                               } @d ];
-                       } else {
-                               $v->{$fld} = 1;
-                       }
+       my $path = shift || die "no path?";
+
+       my $log = $self->_get_logger();
 
+       my $v_file = read_file( $path ) ||
+               $log->logdie("can't open validate path $path: $!");
+
+       my $v;
+       delete( $self->{must_exist} );
+       delete( $self->{must_exist_sf} );
+       delete( $self->{dont_validate} );
+       my $curr_line = 1;
+
+       foreach my $l (split(/[\n\r]+/, $v_file)) {
+               $curr_line++;
+
+               # skip comments and whitespaces
+               next if ($l =~ /^#/ || $l =~ /^\s*$/);
+
+               $l =~ s/^\s+//;
+               $l =~ s/\s+$//;
+
+               my @d = split(/\s+/, $l);
+
+               my $fld = shift @d;
+
+               if ($fld =~ s/!$//) {
+                       $self->{must_exist}->{$fld}++;
+               } elsif ($fld =~ s/-$//) {
+                       $self->{dont_validate}->{$fld}++;
                }
 
-               $log->debug("current validation rules: ", dump($v));
+               $log->logdie("need field name in line $curr_line: $l") unless (defined($fld));
 
-               $self->{rules} = $v;
+               if (@d) {
+                       $v->{$fld} = [ map {
+                               my $sf = $_;
+                               if ( $sf =~ s/!// ) {
+                                       $self->{must_exist_sf}->{ $fld }->{ $sf }++;
+                               };
+                               $sf;
+                       } @d ];
+               } else {
+                       $v->{$fld} = 1;
+               }
 
-               $log->info("validation uses rules from $self->{path}");
        }
 
-       if ( $self->{delimiters} ) {
-               $self->{delimiters_regex} = '(\^[a-z0-9]|' . join('|', @{ $self->{delimiters} }) . ')';
-               $log->info("validation check delimiters with regex $self->{delimiters_regex}");
-       }
+       $log->debug("current validation rules: ", dump($v));
 
-       if ( my $path = $self->{delimiters_path} ) {
-               if ( -e $path ) {
-                       $log->info("using delimiter validation rules from $path");
-                       open(my $d, $path) || $log->fatal("can't open $path: $!");
-                       while(<$d>) {
-                               chomp($d);
-                               if (/^\s*(#*)\s*(\d+)\t+(\d+)\t+(.*)$/) {
-                                       my ($comment,$field,$count,$template) = ($1,$2,$3,$4);
-                                       $self->{_validate_delimiters_templates}->{$field}->{$template} = $count unless ($comment);
-                               } else {
-                                       warn "## ignored $d\n";
-                               }
+       $self->{rules} = $v;
+
+       $log->info("validation uses rules from $path");
+
+       return $curr_line;
+}
+
+=head2 read_validate_delimiters_file
+
+  $validate->read_validate_delimiters_file( 'conf/validate/delimiters/file' );
+
+=cut
+
+sub read_validate_delimiters_file {
+       my $self = shift;
+
+       my $path = shift || die "no path?";
+
+       my $log = $self->_get_logger();
+
+       delete( $self->{_validate_delimiters_templates} );
+       delete( $self->{_delimiters_templates} );
+
+       if ( -e $path ) {
+               $log->info("using delimiter validation rules from $path");
+               open(my $d, $path) || $log->fatal("can't open $path: $!");
+               while(<$d>) {
+                       chomp($d);
+                       if (/^\s*(#*)\s*(\d+)\t+(\d+)\t+(.*)$/) {
+                               my ($comment,$field,$count,$template) = ($1,$2,$3,$4);
+                               $self->{_validate_delimiters_templates}->{$field}->{$template} = $count unless ($comment);
+                       } else {
+                               warn "## ignored $d\n";
                        }
-                       close($d);
-                       #warn "_validate_delimiters_templates = ",dump( $self->{_validate_delimiters_templates} );
-               } else {
-                       $log->warn("delimiters path $path doesn't exist, it will be created after this run");
                }
+               close($d);
+               #warn "_validate_delimiters_templates = ",dump( $self->{_validate_delimiters_templates} );
+       } else {
+               $log->warn("delimiters path $path doesn't exist, it will be created after this run");
        }
-
-       $self ? return $self : return undef;
+       $self->{delimiters_path} = $path;
 }
 
 =head2 validate_rec
@@ -231,6 +273,7 @@ sub validate_rec {
 #                                      $errors->{dump} = $rec_dump if ($rec_dump);
                                } elsif (ref($v) ne 'HASH') {
                                        $errors->{$f}->{missing_subfield} = join(",", @{ $r->{$f} }) . " required";
+                                       $errors->{$f}->{dump} = $v;
                                        next;
                                } else {
 
@@ -251,7 +294,7 @@ sub validate_rec {
                                                        if ( ref($v->{$sf}) eq 'ARRAY' ) {
                                                                $sf_repeatable->{$sf}++;
                                                        };
-                                                       if (! first { $_ eq $sf } @{ $r->{$f} }) {
+                                                       if (! defined first { $_ eq $sf } @{ $r->{$f} }) {
                                                                $errors->{ $f }->{subfield}->{extra}->{$sf}++;
                                                        }
                                                }
@@ -331,7 +374,7 @@ sub reset {
                                $self->{_delimiters_templates}->{$f}->{$t};
                }
        }
-       $log->debug("_accumulated_delimiters_templates = ", sub { dump( $self->{_accumulated_delimiter_templates} ) } );
+       $log->debug("_accumulated_delimiters_templates = ", sub { dump( $self->{_accumulated_delimiters_templates} ) } );
        delete ($self->{_delimiters_templates});
 }
 
@@ -525,18 +568,20 @@ Save accumulated delimiter templates
 sub save_delimiters_templates {
        my $self = shift;
 
-       my $path = $self->{delimiters_path};
-
-       return unless ( $path );
+       my $path = shift;
+       $path ||= $self->{delimiters_path};
 
        my $log = $self->_get_logger;
 
+       $log->logdie("need path") unless ( $path );
+
+
        if ( ! $self->{_accumulated_delimiters_templates} ) {
                $log->error('no _accumulated_delimiters_templates found, reset');
                $self->reset;
        }
 
-       if ( $self->{_delimiters_templates} ) {
+       if ( $self->{_delimiters_templates} ) {
                $log->error('found _delimiters_templates, calling reset');
                $self->reset;
        }
@@ -548,6 +593,8 @@ sub save_delimiters_templates {
        close($d);
 
        $log->info("new delimiters templates saved to $path");
+
+       return 1;
 }
 
 =head1 AUTHOR