source: trunk/gsdl/perllib/plugins/ISISPlug.pm@ 8915

Last change on this file since 8915 was 8762, checked in by mdewsnip, 19 years ago

The files this plugin processes can be exploded by the explode_metadata_database.pl script.

  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 KB
Line 
1###########################################################################
2#
3# ISISPlug.pm -- A plugin for CDS/ISIS databases
4#
5# A component of the Greenstone digital library software
6# from the New Zealand Digital Library Project at the
7# University of Waikato, New Zealand.
8#
9# Copyright 1999-2004 New Zealand Digital Library Project
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation; either version 2 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program; if not, write to the Free Software
23# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24#
25###########################################################################
26
27package ISISPlug;
28
29
30use multiread;
31use SplitPlug;
32
33
34# ISISPlug is a sub-class of SplitPlug.
35sub BEGIN {
36 @ISA = ('SplitPlug');
37}
38
39
40my $arguments =
41 [ { 'name' => "process_exp",
42 'desc' => "{BasPlug.process_exp}",
43 'type' => "regexp",
44 'reqd' => "no",
45 'deft' => &get_default_process_exp() },
46 { 'name' => "block_exp",
47 'desc' => "{BasPlug.block_exp}",
48 'type' => "regexp",
49 'reqd' => "no",
50 'deft' => &get_default_block_exp() },
51 { 'name' => "split_exp",
52 'desc' => "{SplitPlug.split_exp}",
53 'type' => "regexp",
54 'reqd' => "no",
55 'deft' => &get_default_split_exp() },
56
57 # The interesting options
58 { 'name' => "entry_separator",
59 'desc' => "{ISISPlug.entry_separator}",
60 'type' => "string",
61 'reqd' => "no",
62 'deft' => "<br>" },
63 { 'name' => "subfield_separator",
64 'desc' => "{ISISPlug.subfield_separator}",
65 'type' => "string",
66 'reqd' => "no",
67 'deft' => ", " }
68 ];
69
70my $options = { 'name' => "ISISPlug",
71 'desc' => "{ISISPlug.desc}",
72 'abstract' => "no",
73 'inherits' => "yes",
74 'explodes' => "yes",
75 'args' => $arguments };
76
77
78# This plugin processes files with the suffix ".mst"
79sub get_default_process_exp {
80 return q^(?i)(\.mst)$^;
81}
82
83
84# This plugin blocks files with the suffix ".fdt" and ".xrf"
85sub get_default_block_exp {
86 return q^(?i)(\.fdt|\.xrf)$^;
87}
88
89
90# This plugin splits the input text at the "----------" lines
91sub get_default_split_exp {
92 return q^\n----------\n^;
93}
94
95
96sub new
97{
98 my $class = shift(@_);
99
100 my $self = new SplitPlug($class, @_);
101 if (!parsargv::parse(\@_,
102 q^subfield_separator/.*/, ^, \$self->{'subfield_separator'},
103 q^entry_separator/.*/<br>^, \$self->{'entry_separator'},
104 "allow_extra_options")) {
105 print STDERR "\nIncorrect options passed to ISISPlug, check your collect.cfg configuration file\n";
106 die "\n";
107 }
108
109 # To allow for proper inheritance of arguments
110 my $option_list = $self->{'option_list'};
111 push(@{$option_list}, $options);
112 $self->{'plugin_type'} = "ISISPlug";
113
114 return bless $self, $class;
115}
116
117
118sub read_file
119{
120 my $self = shift (@_);
121 my ($filename, $encoding, $language, $textref) = @_;
122
123 my ($databasename) = ($filename =~ /(.*)\.mst$/i);
124
125 # Check the associated .fdt and .xrf files exist
126 # These files must have a lowercase extension for the IsisGdl program to work
127 # Bailing out because of this is kind of crappy but it is only an issue on Unix
128 my $fdtfilename = $databasename . ".fdt";
129 if (! -e $fdtfilename) {
130 die "Error: Could not find ISIS FDT file $fdtfilename.\n";
131 }
132 my $xrffilename = $databasename . ".xrf";
133 if (! -e $xrffilename) {
134 die "Error: Could not find ISIS XRF file $xrffilename.\n";
135 }
136
137 # The text to split is exported from the database by the IsisGdl program
138 open(FILE, "IsisGdl \"$filename\" |");
139
140 my $reader = new multiread();
141 $reader->set_handle('ISISPlug::FILE');
142 $reader->set_encoding($encoding);
143 $reader->read_file($textref);
144
145 close(FILE);
146
147 # Parse the associated ISIS database Field Definition Table file (.fdt)
148 my %fdtmapping = &parse_field_definition_table($fdtfilename);
149
150 # Map the tag numbers to tag names, using the FDT mapping
151 $$textref =~ s/\ntag=(\d+) /\ntag=$fdtmapping{$1}{'title'} /g;
152
153 # Remove the line at the start so it is split and processed properly
154 $$textref =~ s/^----------\n//;
155}
156
157
158sub process
159{
160 my $self = shift (@_);
161 my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
162 my $outhandle = $self->{'outhandle'};
163
164 my $subfield_separator = $self->{'subfield_separator'};
165 my $entry_separator = $self->{'entry_separator'};
166
167 # Report that we're processing the file
168 print STDERR "<Processing n='$file' p='ISISPlug'>\n" if ($gli);
169 print $outhandle "IsisPlug: processing $file\n"
170 if ($self->{'verbosity'}) > 1;
171
172 # Process each line of the ISIS record, one at a time
173 foreach $line (split(/\n/, $$textref)) {
174 $line =~ /^tag=(.*) data=(.+)$/;
175 my $rawtagname = $1;
176 my $rawtagdata = $2;
177 # print STDERR "Raw tag: $rawtagname, Raw data: $rawtagdata\n";
178 next if ($rawtagname eq "");
179
180 # Metadata field names: title case, then remove spaces
181 my $tagname = "";
182 foreach $word (split(/\s+/, $rawtagname)) {
183 substr($word, 0, 1) =~ tr/a-z/A-Z/;
184 $tagname .= $word;
185 }
186
187 # Make sure there is nothing bad in the tag names
188 $tagname =~ s/&//g;
189
190 # Handle each piece of metadata ('%' separated)
191 my $completetagvalue = "";
192 foreach $rawtagvalue (split(/%/, $rawtagdata)) {
193 $completetagvalue .= $entry_separator unless ($completetagvalue eq "");
194
195 # Metadata field values: take care with subfields
196 my $completeentryvalue = "";
197 while ($rawtagvalue ne "") {
198 # If there is a subfield specifier, parse it off
199 my $subfieldname = "";
200 if ($rawtagvalue =~ s/^\^// && $rawtagvalue =~ s/([a-z])//) {
201 $subfieldname = "^$1";
202 }
203
204 # Parse the metadata value off
205 $rawtagvalue =~ s/^([^\^]*)//;
206 my $metadatafieldname = $tagname . $subfieldname;
207 my $metadatafieldvalue = $1;
208
209 # Escape any '<' and '>' characters so they appear correctly in the final collection
210 $metadatafieldvalue =~ s/\</&lt;/g;
211 $metadatafieldvalue =~ s/\>/&gt;/g;
212
213 # Handle Keywords specially
214 if ($metadatafieldname eq "Keywords") {
215 my $keywordmetadatavalue = $metadatafieldvalue;
216 my $keywordlist = "";
217 while ($keywordmetadatavalue =~ s/\<([^\>]+)\>//) {
218 my $keyword = $1;
219 $doc_obj->add_utf8_metadata($cursection, $metadatafieldname, $keyword);
220 $keywordlist .= ", " unless ($keywordlist eq "");
221 $keywordlist .= $keyword;
222 }
223
224 $metadatafieldvalue = $keywordlist;
225 }
226
227 else {
228 $doc_obj->add_utf8_metadata($cursection, $metadatafieldname, $metadatafieldvalue);
229 }
230
231 $completeentryvalue .= $subfield_separator unless ($completeentryvalue eq "");
232 $completeentryvalue .= $metadatafieldvalue;
233 }
234
235 $completetagvalue .= $completeentryvalue;
236 }
237
238 $doc_obj->add_utf8_metadata($cursection, $tagname . "^all", $completetagvalue);
239 }
240
241 # Add the full record as the document text
242 $$textref =~ s/\</&lt;/g;
243 $$textref =~ s/\>/&gt;/g;
244 $doc_obj->add_utf8_text($cursection, $$textref);
245
246 # Add FileFormat metadata
247 $doc_obj->add_utf8_metadata($cursection, "FileFormat", "CDS/ISIS");
248
249 # Record was processed successfully (and there was no document obtained)
250 return 1;
251}
252
253
254sub parse_field_definition_table
255{
256 my $fdtfilename = shift(@_);
257
258 my %fdtmapping = ();
259
260 open(FDT_FILE, "<$fdtfilename") || die "Error: Could not open file $fdtfilename.\n";
261
262 my $amongstdefinitions = 0;
263 foreach $fdtfileline (<FDT_FILE>) {
264 $fdtfileline =~ s/(\s*)$//; # Remove any nasty spaces at the end of the lines
265
266 if ($amongstdefinitions) {
267 my $fieldtitle = substr($fdtfileline, 0, 30);
268 my $fieldsubfields = substr($fdtfileline, 30, 20);
269 my $fieldspecs = substr($fdtfileline, 50);
270
271 # Remove extra spaces
272 $fieldtitle =~ s/(\s*)$//;
273 $fieldsubfields =~ s/(\s*)$//;
274
275 # Map from tag number to metadata field title and subfields
276 my $fieldtag = (split(/ /, $fieldspecs))[0];
277 $fdtmapping{$fieldtag} = { 'title' => $fieldtitle,
278 'subfields' => $fieldsubfields };
279 }
280 elsif ($fdtfileline eq "***") {
281 $amongstdefinitions = 1;
282 }
283 }
284
285 close(FDT_FILE);
286
287 return %fdtmapping;
288}
289
290
2911;
Note: See TracBrowser for help on using the repository browser.