/[webpac2]/trunk/lib/WebPAC/Lookup.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/lib/WebPAC/Lookup.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 234 - (hide annotations)
Tue Dec 6 19:41:17 2005 UTC (18 years, 4 months ago) by dpavlin
File size: 5348 byte(s)
 r245@athlon:  dpavlin | 2005-12-06 20:45:49 +0100
 added support for YAML lookup format

1 dpavlin 4 package WebPAC::Lookup;
2 dpavlin 3
3     use warnings;
4     use strict;
5    
6 dpavlin 15 use base qw/WebPAC::Common WebPAC::Normalize/;
7 dpavlin 3 use File::Slurp;
8 dpavlin 234 use YAML qw/LoadFile/;
9 dpavlin 4 use Data::Dumper;
10 dpavlin 3
11     =head1 NAME
12    
13 dpavlin 4 WebPAC::Lookup - simple normalisation plugin to produce lookup
14 dpavlin 3
15     =head1 VERSION
16    
17 dpavlin 234 Version 0.02
18 dpavlin 3
19     =cut
20    
21 dpavlin 234 our $VERSION = '0.02';
22 dpavlin 3
23     =head1 SYNOPSIS
24    
25     This module will produce in-memory lookups for easy resolution of lookups
26 dpavlin 4 to different records in source files. This will enable you to resolve
27     relational data in source format.
28 dpavlin 3
29 dpavlin 4 It can also be use with C<WebPAC::Tree> to produce tree hierarchies.
30 dpavlin 3
31 dpavlin 4 Lookups are defined in C<conf/lookup/isis.pm>.
32    
33 dpavlin 3 C<lookup> argument is an array of lookups to create. Each lookup must have C<key> and
34     C<val>. Optional parametar C<eval> is perl code to evaluate before storing
35 dpavlin 4 value in lookup.
36 dpavlin 3
37 dpavlin 4 @lookup = [
38 dpavlin 3 { 'key' => 'd:v900', 'val' => 'v250^a' },
39     { 'eval' => '"v901^a" eq "Podruèje"',
40     'key' => 'pa:v561^4:v562^4:v461^1',
41     'val' => 'v900' },
42     ];
43    
44 dpavlin 30 Just for a reference, lookup data is internally stored in
45     C<< $self->{'_lookup_data'} >>.
46 dpavlin 3
47     =head1 FUNCTIONS
48    
49     =head2 new
50    
51     Create new lookup object.
52    
53 dpavlin 4 my $lookup = new WebPAC::Lookup(
54     lookup_file => '/path/to/conf/lookup/lookup.pm',
55 dpavlin 12 is_lookup_regex => 'lookup{[^\{\}]+}';
56     save_lookup_regex => 'lookup{([^\{\}]+)}';
57 dpavlin 3 );
58    
59     =cut
60    
61     sub new {
62     my $class = shift;
63     my $self = {@_};
64     bless($self, $class);
65    
66     my $log = $self->_get_logger();
67    
68 dpavlin 4 my $lookup_file = $self->{'lookup_file'} || $log->logconfess("need path to lookup file in lookup_file parametar");
69 dpavlin 3
70 dpavlin 4 my $lookup_code = read_file($lookup_file) || $log->logconfess("can't read lookup file $lookup_file: $!");
71 dpavlin 3
72 dpavlin 234 if ($lookup_file =~ m#\.pm$#) {
73 dpavlin 3 no strict 'vars';
74 dpavlin 4 do $lookup_file or $log->logdie("Failed to read configuration parameters '$lookup_file' $! $@");
75     $self->{'lookup_def'} = \@lookup || $log->logdie("lookup config $lookup_file doesn't produce \@lookup array");
76 dpavlin 234 } elsif ($lookup_file =~ m#\.(:?yml|yaml)$#) {
77     my $yaml = LoadFile( $lookup_file ) || $log->logdie("lookup YAML file $lookup_file error: $!");
78     $self->{'lookup_def'} = $yaml->{lookup} || $log->logdie("lookup YAML file $lookup_file should begin with 'lookup:'");
79     } else {
80     $log->logide("unsupported lookup file $lookup_file");
81 dpavlin 3 }
82    
83 dpavlin 234 $log->logconfess("lookup config file isn't ARRAY but ", sub { Dumper( $self->{'lookup_def'} ) }) if ($self->{'lookup_def'} !~ /ARRAY/o);
84 dpavlin 3
85 dpavlin 12 $self->{'is_lookup_regex'} ||= 'lookup{[^\{\}]+}';
86     $self->{'save_lookup_regex'} ||= 'lookup{([^\{\}]+)}';
87    
88    
89     $self->{'LOOKUP_REGEX'} = qr/$self->{'is_lookup_regex'}/;
90     $self->{'LOOKUP_REGEX_SAVE'} = qr/$self->{'save_lookup_regex'}/;
91    
92     $log->debug("regexps: ", $self->{'LOOKUP_REGEX'}, " ", $self->{'LOOKUP_REGEX_SAVE'});
93    
94 dpavlin 3 $self ? return $self : return undef;
95     }
96    
97 dpavlin 4 =head2 add
98 dpavlin 3
99     Create lookup from record using lookup definition.
100    
101 dpavlin 7 $self->add($rec);
102 dpavlin 3
103 dpavlin 4 Returns true if this record produced lookup.
104 dpavlin 3
105     =cut
106    
107 dpavlin 4 sub add($) {
108 dpavlin 3 my $self = shift;
109    
110     my $log = $self->_get_logger();
111    
112     my $rec = shift || $log->logconfess("need record to create lookup");
113     $log->logconfess("need HASH as first argument!") if ($rec !~ /HASH/o);
114 dpavlin 4 $log->logconfess("need HASH as first argument!") if ($self->{'lookup_def'} !~ /ARRAY/o);
115 dpavlin 3
116 dpavlin 4 my $n = 0;
117    
118     foreach my $i (@{ $self->{'lookup_def'} }) {
119 dpavlin 3 $log->logconfess("need key") unless defined($i->{'key'});
120     $log->logconfess("need val") unless defined($i->{'val'});
121    
122 dpavlin 4 $n++;
123    
124 dpavlin 3 if (defined($i->{'eval'})) {
125     # eval first, so we can skip fill_in for key and val
126     my $eval = $self->fill_in($rec,$i->{'eval'}) || next;
127     if ($self->_eval($eval)) {
128     my $key = $self->fill_in($rec,$i->{'key'}) || next;
129     my @val = $self->fill_in($rec,$i->{'val'}) || next;
130     $log->debug("stored $key = ",sub { join(" | ",@val) });
131 dpavlin 30 push @{$self->{'_lookup_data'}->{$key}}, @val;
132 dpavlin 3 }
133     } else {
134     my $key = $self->fill_in($rec,$i->{'key'}) || next;
135     my @val = $self->fill_in($rec,$i->{'val'}) || next;
136     $log->debug("stored $key = ",sub { join(" | ",@val) });
137 dpavlin 30 push @{$self->{'_lookup_data'}->{$key}}, @val;
138 dpavlin 3 }
139     }
140 dpavlin 4
141     return $n;
142 dpavlin 3 }
143    
144 dpavlin 7 =head2 lookup
145    
146     Perform lookups on format supplied to it.
147    
148     my $text = $lookup->lookup('[v900]');
149    
150     Lookups can be nested (like C<[d:[a:[v900]]]>).
151    
152     =cut
153    
154     sub lookup {
155     my $self = shift;
156    
157     my $log = $self->_get_logger();
158    
159     my $tmp = shift || $log->logconfess("need format");
160    
161 dpavlin 12 if ($tmp =~ $self->{'LOOKUP_REGEX'}) {
162 dpavlin 7 my @in = ( $tmp );
163    
164     $log->debug("lookup for: ",$tmp);
165    
166     my @out;
167     while (my $f = shift @in) {
168 dpavlin 12 if ($f =~ $self->{'LOOKUP_REGEX_SAVE'}) {
169 dpavlin 7 my $k = $1;
170 dpavlin 30 if ($self->{'_lookup_data'}->{$k}) {
171     foreach my $nv (@{$self->{'_lookup_data'}->{$k}}) {
172 dpavlin 7 my $tmp2 = $f;
173     $tmp2 =~ s/lookup{$k}/$nv/g;
174     push @in, $tmp2;
175     }
176     } else {
177     undef $f;
178     }
179     } elsif ($f) {
180     push @out, $f;
181     }
182     }
183     $log->logconfess("return is array and it's not expected!") unless wantarray;
184     return @out;
185     } else {
186     return $tmp;
187     }
188     }
189    
190 dpavlin 12 =head2 regex
191    
192     Returns precompiled regex for lookup format.
193    
194     if ($foo =~ $lookup->reges) { ... }
195    
196     =cut
197    
198     sub regex {
199     my $self = shift;
200    
201     return $self->{'LOOKUP_REGEX'};
202     }
203    
204 dpavlin 3 =head1 AUTHOR
205    
206     Dobrica Pavlinusic, C<< <dpavlin@rot13.org> >>
207    
208     =head1 COPYRIGHT & LICENSE
209    
210     Copyright 2005 Dobrica Pavlinusic, All Rights Reserved.
211    
212     This program is free software; you can redistribute it and/or modify it
213     under the same terms as Perl itself.
214    
215     =cut
216    
217 dpavlin 4 1; # End of WebPAC::Lookup

  ViewVC Help
Powered by ViewVC 1.1.26