a1bfeff7ebac266c9d78097173dff6ebeda224d7
[srvgit] / Koha / Z3950Responder / RPN.pm
1 #!/usr/bin/perl
2
3 # Copyright The National Library of Finland 2018
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it under thes
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 3 of the License, or (at your option) any later
10 # version.
11 #
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20 use Modern::Perl;
21
22 =head1 NAME
23
24 Koha::Z3950Responder::RPN
25
26 =head1 SYNOPSIS
27
28 Overrides for the C<Net::Z3950::RPN> classes adding a C<to_koha> method that
29 converts the query to a syntax that C<Koha::SearchEngine> understands.
30
31 =head1 DESCRIPTION
32
33 The method used here is described in C<samples/render-search.pl> of
34 C<Net::Z3950::SimpleServer>.
35
36 =cut
37
38 package Net::Z3950::RPN::Term;
39 sub to_koha {
40     my ($self, $mappings) = @_;
41
42     my $attrs = $self->{'attributes'};
43     my $fields = $mappings->{use}{default} // '_all';
44     my $split = 0;
45     my $prefix = '';
46     my $suffix = '';
47     my $term = $self->{'term'};
48     utf8::decode($term);
49
50     if ($attrs) {
51         foreach my $attr (@$attrs) {
52             if ($attr->{'attributeType'} == 1) { # use
53                 my $use = $attr->{'attributeValue'};
54                 $fields = $mappings->{use}{$use} if defined $mappings->{use}{$use};
55             } elsif ($attr->{'attributeType'} == 4) { # structure
56                 $split = 1 if ($attr->{'attributeValue'} == 2);
57             } elsif ($attr->{'attributeType'} == 5) { # truncation
58                 my $truncation = $attr->{'attributeValue'};
59                 $prefix = '*' if ($truncation == 2 || $truncation == 3);
60                 $suffix = '*' if ($truncation == 1 || $truncation == 3);
61             }
62         }
63     }
64
65     $fields = [$fields] unless ref($fields) eq 'ARRAY';
66
67     if ($split) {
68         my @terms;
69         foreach my $word (split(/\s/, $term)) {
70             $word =~ s/^[\,\.;:\\\/\"\'\-\=]+//g;
71             $word =~ s/[\,\.;:\\\/\"\'\-\=]+$//g;
72             next if (!$word);
73             $word = $self->escape($word);
74             my @words;
75             foreach my $field (@{$fields}) {
76                 push(@words, "$field:($prefix$word$suffix)");
77             }
78             push (@terms, join(' OR ', @words));
79         }
80         return '(' . join(' AND ', @terms) . ')';
81     }
82
83     my @terms;
84     $term = $self->escape($term);
85     foreach my $field (@{$fields}) {
86         push(@terms, "$field:($prefix$term$suffix)");
87     }
88     return '(' . join(' OR ', @terms) . ')';
89 }
90
91 sub escape {
92     my ($self, $term) = @_;
93
94     $term =~ s/([()])/\\$1/g;
95     return $term;
96 }
97
98 package Net::Z3950::RPN::And;
99 sub to_koha {
100     my ($self, $mappings) = @_;
101
102     return '(' . $self->[0]->to_koha($mappings) . ' AND ' .
103                  $self->[1]->to_koha($mappings) . ')';
104 }
105
106 package Net::Z3950::RPN::Or;
107 sub to_koha {
108     my ($self, $mappings) = @_;
109
110     return '(' . $self->[0]->to_koha($mappings) . ' OR ' .
111                  $self->[1]->to_koha($mappings) . ')';
112 }
113
114 package Net::Z3950::RPN::AndNot;
115 sub to_koha {
116     my ($self, $mappings) = @_;
117
118     return '(' . $self->[0]->to_koha($mappings) . ' NOT ' .
119                  $self->[1]->to_koha($mappings) . ')';
120 }
121
122 1;