source: tags/gsdl-2_53-distribution/gsdl/perllib/lucenebuildproc.pm@ 9303

Last change on this file since 9303 was 9214, checked in by kjdon, 19 years ago

now set a gdbm_level in buildproc, so can tell whether to number documents by doc num or section num

  • Property svn:keywords set to Author Date Id Revision
File size: 9.5 KB
Line 
1###########################################################################
2#
3# lucenebuildproc.pm -- perl wrapper for building index with Lucene
4# A component of the Greenstone digital library software
5# from the New Zealand Digital Library Project at the
6# University of Waikato, New Zealand.
7#
8# Copyright (C) 1999 New Zealand Digital Library Project
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24###########################################################################
25
26package lucenebuildproc;
27
28# This document processor outputs a document
29# for lucene to process
30
31# Use same basic XML structure setup by mgppbuilder/mgppbuildproc
32
33use mgppbuildproc;
34use ghtml;
35
36sub BEGIN {
37 @lucenebuildproc::ISA = ('mgppbuildproc');
38}
39
40
41sub new {
42 my $class = shift @_;
43 my $self = new mgppbuildproc (@_);
44
45 return bless $self, $class;
46}
47
48sub set_gdbm_level {
49 my $self = shift(@_);
50 my ($level) = @_;
51
52 $self->{'gdbm_level'} = $level;
53}
54sub preprocess_text {
55 my $self = shift (@_);
56 my ($text, $strip_html, $para) = @_;
57
58 my ($outtext) = "";
59 if ($strip_html) {
60 while ($text =~ /<([^>]*)>/ && $text ne "") {
61
62 my $tag = $1;
63 $outtext .= $`." "; #add everything before the matched tag
64 $text = $'; #'everything after the matched tag
65 if ($para && $tag =~ /^\s*p\s/i) {
66 $outtext .= $para;
67 }
68 elsif ($tag =~ /^pre$/) { # a pre tag
69 $text =~ /<\/pre>/; # find the closing pre tag
70 my $tmp_text = $`; #everything before the closing pre tag
71 $text = $'; #'everything after the </pre>
72 $tmp_text =~ s/[<>]//g; # remove all < and >
73 $outtext.= $tmp_text . " ";
74 }
75 }
76
77 $outtext .= $text; # add any remaining text
78 } #if strip_html
79 else {
80 $outtext = $text;
81 }
82 #if ($para) {
83 #$text =~ s/(<p\b)/$para$1/gi;
84 #return $text;
85 #}
86
87 # remove entities
88 $outtext =~ s/&\w{1,10};//g;
89
90 return $outtext;
91}
92
93sub text {
94 my $self = shift (@_);
95 my ($doc_obj,$file) = @_;
96 my $handle = $self->{'output_handle'};
97 my $outhandle = $self->{'outhandle'};
98 my $indexed_doc = 1;
99
100 # only output this document if it is one to be indexed
101 return if ($doc_obj->get_doc_type() ne "indexed_doc");
102
103 # see if this document belongs to this subcollection
104 foreach my $indexexp (@{$self->{'indexexparr'}}) {
105 $indexed_doc = 0;
106 my ($field, $exp, $options) = split /\//, $indexexp;
107 if (defined ($field) && defined ($exp)) {
108 my ($bool) = $field =~ /^(.)/;
109 $field =~ s/^.// if $bool eq '!';
110 if ($field =~ /^filename$/i) {
111 $field = $doc_obj->get_source_filename();
112 } else {
113 $field = $doc_obj->get_metadata_element($doc_obj->get_top_section(), $field);
114 }
115 next unless defined $field;
116 if ($bool eq '!') {
117 if ($options =~ /^i$/i) {
118 if ($field !~ /$exp/i) {$indexed_doc = 1; last;}
119 } else {
120 if ($field !~ /$exp/) {$indexed_doc = 1; last;}
121 }
122 } else {
123 if ($options =~ /^i$/i) {
124 if ($field =~ /$exp/i) {$indexed_doc = 1; last;}
125 } else {
126 if ($field =~ /$exp/) {$indexed_doc = 1; last;}
127 }
128 }
129 }
130 }
131
132 # this is another document
133 $self->{'num_docs'} += 1;
134
135 # get the parameters for the output
136 # split on : just in case there is subcoll and lang stuff
137 my ($fields) = split (/:/, $self->{'index'});
138
139 my $doc_level = $mgppbuildproc::level_map{'document'};
140 my $gs2ns = 'xmlns:gs2="http://www.greenstone.org/gs2"';
141
142 my $levels = $self->{'levels'};
143 my $ldoc_level = $levels->{'document'};
144 my $lsec_level = $levels->{'section'};
145 my $lpar_level = $levels->{'paragraph'};
146
147 my $docid="";
148 if ($ldoc_level) {
149 if ($self->{'gdbm_level'} eq 'document') {
150 my $doc_sec_num = $self->{'num_docs'};
151 $docid = "gs2:id=\"$doc_sec_num\"";
152 } else {
153 # default is section level
154 my $doc_sec_num = $self->{'num_sections'}+1;
155 $docid = "gs2:id=\"$doc_sec_num\"";
156 }
157 }
158 my $documenttag = "<$doc_level $gs2ns file=\"$file\" $docid >\n";
159 my $documentendtag = "\n</$doc_level>\n";
160
161 my ($sectiontag) = "";
162 if ($lsec_level) {
163 $sectiontag = $mgppbuildproc::level_map{'section'};
164 }
165 my ($parastarttag) = "";
166 my ($paraendtag) = "";
167 if ($self->{'levels'}->{'paragraph'}) {
168 if ($self->{'strip_html'}) {
169 $parastarttag = "<".$mgppbuildproc::level_map{'paragraph'}.">";
170 $paraendtag = "</".$mgppbuildproc::level_map{'paragraph'}.">";
171 } else {
172 print $outhandle "Paragraph level can not be used with no_strip_html!. Not indexing Paragraphs.\n";
173 }
174 }
175
176 my $doc_section = 0; # just for this document
177
178 my $text = "";
179 $text .= $documenttag;
180 # get the text for this document
181 my $section = $doc_obj->get_top_section();
182 while (defined $section) {
183 # update a few statistics
184 $doc_section++;
185 $self->{'num_sections'} += 1;
186
187 if ($sectiontag ne "") {
188 my $secid = "gs2:id=\"".$self->{'num_sections'}."\"";
189 $text .= "\n<$sectiontag $secid >\n";
190 }
191
192 # if we are doing subcollections, then some docs shouldn't be indexed.
193 # but we need to put the section tag placeholders in there so the
194 # sections match up with gdbm db
195 if ($indexed_doc) {
196 #if ($self->{'indexing_text'}) {
197 # $text .= "$parastarttag"; # only add para tags for indexing
198 # note that we assume that metadata will not be asked for for the compressed text, so we add para tags without checking for indexing_text
199 # }
200 $self->{'num_bytes'} += $doc_obj->get_text_length ($section);
201 foreach my $field (split (/,/, $fields)) {
202 # only deal with this field if it doesn't start with top or
203 # this is the first section
204 my $real_field = $field;
205 if (!($real_field =~ s/^top//) || ($doc_section == 1)) {
206 my $new_text = "";
207 my $tmp_text = "";
208 if ($real_field eq "text") {
209 if ($self->{'indexing_text'}) { #tag the text with <Text>...</Text>, add the <Paragraph> tags and strip out html if needed
210 $new_text .= "$parastarttag<TX index=\"1\">\n";
211 $tmp_text .= $doc_obj->get_text ($section);
212 if ($parastarttag =~ "") {
213 # we don't want to individually tag each paragraph if not doing para indexing
214 $tmp_text = $self->preprocess_text($tmp_text, $self->{'strip_html'}, "");
215 } else {
216 $tmp_text = $self->preprocess_text($tmp_text, $self->{'strip_html'}, "</TX>$paraendtag$parastarttag<TX index=\"1\">");
217 }
218
219 $new_text .= "$tmp_text</TX>$paraendtag\n";
220 #if (!defined $self->{'indexfields'}->{'TextOnly'}) {
221 #$self->{'indexfields'}->{'TextOnly'} = 1;
222 #}
223 }
224 else { # leave html stuff in, but escape the tags, and dont add Paragraph tags - never retrieve paras at the moment
225 if ($self->{'store_text'}) {
226 $tmp_text .= $doc_obj->get_text ($section);
227 &ghtml::htmlsafe($tmp_text);
228 $new_text .= $tmp_text;
229 }
230 }
231 } else { # metadata field
232 if ($real_field eq "allfields") { #ignore
233 }
234 elsif ($real_field eq "metadata") { # insert all metadata
235 #except gsdl stuff
236 my $shortname = "";
237 my $metadata = $doc_obj->get_all_metadata ($section);
238 foreach $pair (@$metadata) {
239 my ($mfield, $mvalue) = (@$pair);
240 # check fields here, maybe others dont want - change to use dontindex!!
241 if ($mfield ne "Identifier"
242 && $mfield !~ /^gsdl/
243 && $mfield ne "classifytype"
244 && $mfield ne "assocfilepath"
245 && defined $mvalue && $mvalue ne "") {
246
247 if (defined $self->{'indexfieldmap'}->{$mfield}) {
248 $shortname = $self->{'indexfieldmap'}->{$mfield};
249 }
250 else {
251 $shortname = $self->create_shortname($mfield);
252 $self->{'indexfieldmap'}->{$mfield} = $shortname;
253 $self->{'indexfieldmap'}->{$shortname} = 1;
254 }
255 $new_text .= "$parastarttag<$shortname index=\"1\">$mvalue</$shortname>$paraendtag\n";
256 if (!defined $self->{'indexfields'}->{$mfield}) {
257 $self->{'indexfields'}->{$mfield} = 1;
258 }
259 }
260 }
261
262 }
263 else { #individual metadata specified
264 my $shortname="";
265 #if (!defined $self->{'indexfields'}->{$real_field}) {
266 #$self->{'indexfields'}->{$real_field} = 1;
267 #}
268 if (defined $self->{'indexfieldmap'}->{$real_field}) {
269 $shortname = $self->{'indexfieldmap'}->{$real_field};
270 }
271 else {
272 $shortname = $self->create_shortname($real_field);
273 $self->{'indexfieldmap'}->{$real_field} = $shortname;
274 $self->{'indexfieldmap'}->{$shortname} = 1;
275 }
276 foreach $item (@{$doc_obj->get_metadata ($section, $real_field)}) {
277 $new_text .= "$parastarttag<$shortname index=\"1\">$item</$shortname>$paraendtag\n";
278 # remove entities
279 $new_text =~ s/&\w{1,10};//g;
280 }
281 }
282
283 }
284
285 # filter the text
286 $self->filter_text ($field, $new_text);
287 $self->{'num_processed_bytes'} += length ($new_text);
288 $text .= "$new_text";
289 }
290 }
291 } # if (indexed_doc)
292
293 $text .= "\n</$sectiontag>\n" if ($sectiontag ne "");
294
295 $section = $doc_obj->get_next_section($section);
296 } #while defined section
297 print $handle "$text\n$documentendtag";
298}
299
3001;
301
Note: See TracBrowser for help on using the repository browser.