/[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 251 - (hide annotations)
Thu Dec 15 14:12:00 2005 UTC (18 years, 4 months ago) by dpavlin
File size: 5456 byte(s)
various updates to make lookups work (but they don't still)

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 dpavlin 251 $log->debug("lookup_def: " . Dumper( $self->{lookup_def} ));
83 dpavlin 3
84 dpavlin 234 $log->logconfess("lookup config file isn't ARRAY but ", sub { Dumper( $self->{'lookup_def'} ) }) if ($self->{'lookup_def'} !~ /ARRAY/o);
85 dpavlin 3
86 dpavlin 251 $self->{'is_lookup_regex'} ||= 'lookup{\[[^\{\}]+\]}';
87 dpavlin 12 $self->{'save_lookup_regex'} ||= 'lookup{([^\{\}]+)}';
88    
89    
90     $self->{'LOOKUP_REGEX'} = qr/$self->{'is_lookup_regex'}/;
91     $self->{'LOOKUP_REGEX_SAVE'} = qr/$self->{'save_lookup_regex'}/;
92    
93 dpavlin 251 $log->debug("regexps lookup:", $self->{'LOOKUP_REGEX'}, " save:", $self->{'LOOKUP_REGEX_SAVE'});
94 dpavlin 12
95 dpavlin 3 $self ? return $self : return undef;
96     }
97    
98 dpavlin 4 =head2 add
99 dpavlin 3
100     Create lookup from record using lookup definition.
101    
102 dpavlin 7 $self->add($rec);
103 dpavlin 3
104 dpavlin 4 Returns true if this record produced lookup.
105 dpavlin 3
106     =cut
107    
108 dpavlin 251 sub add {
109 dpavlin 3 my $self = shift;
110    
111     my $log = $self->_get_logger();
112    
113     my $rec = shift || $log->logconfess("need record to create lookup");
114     $log->logconfess("need HASH as first argument!") if ($rec !~ /HASH/o);
115 dpavlin 4 $log->logconfess("need HASH as first argument!") if ($self->{'lookup_def'} !~ /ARRAY/o);
116 dpavlin 3
117 dpavlin 4 my $n = 0;
118    
119     foreach my $i (@{ $self->{'lookup_def'} }) {
120 dpavlin 251 $log->logconfess("need key in ", Dumper($i) ) unless defined($i->{'key'});
121     $log->logconfess("need val in ", Dumper($i) ) unless defined($i->{'val'});
122 dpavlin 3
123 dpavlin 4 $n++;
124    
125 dpavlin 3 if (defined($i->{'eval'})) {
126     # eval first, so we can skip fill_in for key and val
127     my $eval = $self->fill_in($rec,$i->{'eval'}) || next;
128     if ($self->_eval($eval)) {
129     my $key = $self->fill_in($rec,$i->{'key'}) || next;
130     my @val = $self->fill_in($rec,$i->{'val'}) || next;
131     $log->debug("stored $key = ",sub { join(" | ",@val) });
132 dpavlin 30 push @{$self->{'_lookup_data'}->{$key}}, @val;
133 dpavlin 3 }
134     } else {
135     my $key = $self->fill_in($rec,$i->{'key'}) || next;
136     my @val = $self->fill_in($rec,$i->{'val'}) || next;
137     $log->debug("stored $key = ",sub { join(" | ",@val) });
138 dpavlin 30 push @{$self->{'_lookup_data'}->{$key}}, @val;
139 dpavlin 3 }
140     }
141 dpavlin 4
142     return $n;
143 dpavlin 3 }
144    
145 dpavlin 7 =head2 lookup
146    
147     Perform lookups on format supplied to it.
148    
149     my $text = $lookup->lookup('[v900]');
150    
151     Lookups can be nested (like C<[d:[a:[v900]]]>).
152    
153     =cut
154    
155     sub lookup {
156     my $self = shift;
157    
158     my $log = $self->_get_logger();
159    
160     my $tmp = shift || $log->logconfess("need format");
161    
162 dpavlin 12 if ($tmp =~ $self->{'LOOKUP_REGEX'}) {
163 dpavlin 7 my @in = ( $tmp );
164    
165     $log->debug("lookup for: ",$tmp);
166    
167     my @out;
168     while (my $f = shift @in) {
169 dpavlin 12 if ($f =~ $self->{'LOOKUP_REGEX_SAVE'}) {
170 dpavlin 7 my $k = $1;
171 dpavlin 30 if ($self->{'_lookup_data'}->{$k}) {
172     foreach my $nv (@{$self->{'_lookup_data'}->{$k}}) {
173 dpavlin 7 my $tmp2 = $f;
174     $tmp2 =~ s/lookup{$k}/$nv/g;
175     push @in, $tmp2;
176     }
177     } else {
178     undef $f;
179     }
180     } elsif ($f) {
181     push @out, $f;
182     }
183     }
184     $log->logconfess("return is array and it's not expected!") unless wantarray;
185     return @out;
186     } else {
187     return $tmp;
188     }
189     }
190    
191 dpavlin 12 =head2 regex
192    
193     Returns precompiled regex for lookup format.
194    
195     if ($foo =~ $lookup->reges) { ... }
196    
197     =cut
198    
199     sub regex {
200     my $self = shift;
201    
202     return $self->{'LOOKUP_REGEX'};
203     }
204    
205 dpavlin 3 =head1 AUTHOR
206    
207     Dobrica Pavlinusic, C<< <dpavlin@rot13.org> >>
208    
209     =head1 COPYRIGHT & LICENSE
210    
211     Copyright 2005 Dobrica Pavlinusic, All Rights Reserved.
212    
213     This program is free software; you can redistribute it and/or modify it
214     under the same terms as Perl itself.
215    
216     =cut
217    
218 dpavlin 4 1; # End of WebPAC::Lookup

  ViewVC Help
Powered by ViewVC 1.1.26