|
Lines 471-507
sub _process_mappings {
Link Here
|
| 471 |
# Copy (scalar) data since can have multiple targets |
471 |
# Copy (scalar) data since can have multiple targets |
| 472 |
# with differing options for (possibly) mutating data |
472 |
# with differing options for (possibly) mutating data |
| 473 |
# so need a different copy for each |
473 |
# so need a different copy for each |
| 474 |
my $_data = $data; |
474 |
my $data_copy = $data; |
| 475 |
if (defined $options->{substr}) { |
475 |
if (defined $options->{substr}) { |
| 476 |
my ($start, $length) = @{$options->{substr}}; |
476 |
my ($start, $length) = @{$options->{substr}}; |
| 477 |
$_data = length($data) > $start ? substr $data, $start, $length : ''; |
477 |
$data_copy = length($data) > $start ? substr $data_copy, $start, $length : ''; |
|
|
478 |
} |
| 479 |
|
| 480 |
# Add data to tokens array for callbacks processing |
| 481 |
my $tokens = [$data_copy]; |
| 482 |
|
| 483 |
# Tokenize callbacks takes as token (possibly tokenized subfield data) |
| 484 |
# as argument, and returns a possibly different list of tokens. |
| 485 |
# Note that this list also might be empty. |
| 486 |
if (defined $options->{tokenize_callbacks}) { |
| 487 |
foreach my $callback (@{$options->{tokenize_callbacks}}) { |
| 488 |
# Pass each token to current callback which returns a list |
| 489 |
# (scalar is fine too) resulting either in a list or |
| 490 |
# a list of lists that will be flattened by perl. |
| 491 |
# The next callback will recieve the possibly expanded list of tokens. |
| 492 |
$tokens = [ map { $callback->($_) } @{$tokens} ]; |
| 493 |
} |
| 478 |
} |
494 |
} |
| 479 |
if (defined $options->{value_callbacks}) { |
495 |
if (defined $options->{value_callbacks}) { |
| 480 |
$_data = reduce { $b->($a) } ($_data, @{$options->{value_callbacks}}); |
496 |
$tokens = [ map { reduce { $b->($a) } ($_, @{$options->{value_callbacks}}) } @{$tokens} ]; |
| 481 |
} |
497 |
} |
| 482 |
if (defined $options->{filter_callbacks}) { |
498 |
if (defined $options->{filter_callbacks}) { |
| 483 |
# Skip mapping unless all filter callbacks return true |
499 |
my @tokens_filtered; |
| 484 |
next unless all { $_data = $_->($_data) } @{$options->{filter_callbacks}}; |
500 |
foreach my $_data (@{$tokens}) { |
|
|
501 |
if ( all { $_->($_data) } @{$options->{filter_callbacks}} ) { |
| 502 |
push @tokens_filtered, $_data; |
| 503 |
} |
| 504 |
} |
| 505 |
# Overwrite $tokens with filtered values |
| 506 |
$tokens = \@tokens_filtered; |
| 485 |
} |
507 |
} |
|
|
508 |
# Skip mapping if all values has been removed |
| 509 |
next unless @{$tokens}; |
| 510 |
|
| 486 |
if (defined $options->{property}) { |
511 |
if (defined $options->{property}) { |
| 487 |
$_data = { |
512 |
$tokens = [ map { { $options->{property} => $_ } } @{$tokens} ]; |
| 488 |
$options->{property} => $_data |
|
|
| 489 |
} |
| 490 |
} |
513 |
} |
| 491 |
if (defined $options->{nonfiling_characters_indicator}) { |
514 |
if (defined $options->{nonfiling_characters_indicator}) { |
| 492 |
my $nonfiling_chars = $meta->{field}->indicator($options->{nonfiling_characters_indicator}); |
515 |
my $nonfiling_chars = $meta->{field}->indicator($options->{nonfiling_characters_indicator}); |
| 493 |
$nonfiling_chars = looks_like_number($nonfiling_chars) ? int($nonfiling_chars) : 0; |
516 |
$nonfiling_chars = looks_like_number($nonfiling_chars) ? int($nonfiling_chars) : 0; |
| 494 |
if ($nonfiling_chars) { |
517 |
# Nonfiling chars does not make sense for multiple tokens |
| 495 |
$_data = substr $_data, $nonfiling_chars; |
518 |
# Only apply on first element |
| 496 |
} |
519 |
$tokens->[0] = substr $tokens->[0], $nonfiling_chars; |
| 497 |
} |
520 |
} |
| 498 |
|
521 |
|
| 499 |
$record_document->{$target} //= []; |
522 |
$record_document->{$target} //= []; |
| 500 |
if( ref $_data eq 'ARRAY' ){ |
523 |
push @{$record_document->{$target}}, @{$tokens}; |
| 501 |
push @{$record_document->{$target}}, @{$_data}; |
|
|
| 502 |
} else { |
| 503 |
push @{$record_document->{$target}}, $_data; |
| 504 |
} |
| 505 |
} |
524 |
} |
| 506 |
} |
525 |
} |
| 507 |
|
526 |
|
|
Lines 897-912
sub _field_mappings {
Link Here
|
| 897 |
}; |
916 |
}; |
| 898 |
} |
917 |
} |
| 899 |
elsif ($target_type eq 'year') { |
918 |
elsif ($target_type eq 'year') { |
| 900 |
$default_options->{filter_callbacks} //= []; |
919 |
$default_options->{tokenize_callbacks} //= []; |
| 901 |
push @{$default_options->{filter_callbacks}}, sub { |
920 |
# Only accept years containing digits and "u" |
|
|
921 |
push @{$default_options->{tokenize_callbacks}}, sub { |
| 902 |
my ($value) = @_; |
922 |
my ($value) = @_; |
| 903 |
my @years = (); |
923 |
my @years = ( $value =~ /[0-9u]{4}/g ); |
| 904 |
my @field_years = ( $value =~ /[0-9u]{4}/g ); |
924 |
return @years; |
| 905 |
foreach my $year (@field_years){ |
925 |
}; |
| 906 |
$year =~ s/[u]/0/g; |
926 |
|
| 907 |
push @years, $year; |
927 |
$default_options->{value_callbacks} //= []; |
| 908 |
} |
928 |
# Replace "u" with "0" for sorting |
| 909 |
return \@years; |
929 |
push @{$default_options->{value_callbacks}}, sub { |
|
|
930 |
my ($value) = @_; |
| 931 |
$value =~ s/[u]/0/g; |
| 932 |
return $value; |
| 910 |
}; |
933 |
}; |
| 911 |
} |
934 |
} |
| 912 |
|
935 |
|