source: trunk/gsdl/perllib/classify/Hierarchy.pm@ 8728

Last change on this file since 8728 was 8716, checked in by kjdon, 20 years ago

added some changes made by Emanuel Dejanu (Simple Words)

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 9.2 KB
Line 
1###########################################################################
2#
3# Hierarchy.pm --
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
26# classifier plugin for generating hierarchical classifications
27
28
29package Hierarchy;
30
31use BasClas;
32use util;
33use cfgread;
34use sorttools;
35
36sub BEGIN {
37 @Hierarchy::ISA = ('BasClas');
38}
39
40my $arguments =
41 [ { 'name' => "metadata",
42 'desc' => "{Hierarchy.metadata}",
43 'type' => "metadata",
44 'reqd' => "yes" },
45 { 'name' => "hfile",
46 'desc' => "{Hierarchy.hfile}",
47 'type' => "string",
48 'deft' => "",
49 'reqd' => "yes" },
50 { 'name' => "buttonname",
51 'desc' => "{BasClas.buttonname}",
52 'type' => "string",
53 'deft' => "",
54 'reqd' => "no" },
55 { 'name' => "sort",
56 'desc' => "{Hierarchy.sort}",
57 'type' => "string",
58 'deft' => "{BasClas.metadata.deft}",
59 'reqd' => "no" },
60 { 'name' => "reverse_sort",
61 'desc' => "{Hierarchy.reverse_sort}",
62 'type' => "flag",
63 'reqd' => "no" },
64 { 'name' => "hlist_at_top",
65 'desc' => "{Hierarchy.hlist_at_top}",
66 'type' => "flag",
67 'reqd' => "no" } ];
68
69my $options =
70{ 'name' => "Hierarchy",
71 'desc' => "{Hierarchy.desc}",
72 'abstract' => "no",
73 'inherits' => "yes",
74 'args' => $arguments };
75
76
77sub new {
78 my $class = shift (@_);
79 my $self = new BasClas($class, @_);
80
81 my $option_list = $self->{'option_list'};
82 push( @{$option_list}, $options );
83
84 if ($self->{'info_only'}) {
85 # created from classinfo.pl - don't need to parse the arguments
86 return bless $self, $class;
87 }
88
89 my ($hfile, $metadata, $sortname, $reverse_sort, $title, $hlist_at_top);
90
91 if (!parsargv::parse(\@_,
92 q^buttonname/.*/^, \$title,
93 q^sort/.*/^, \$sortname,
94 q^reverse_sort^, \$reverse_sort,
95 q^hfile/.*/^, \$hfile,
96 q^metadata/.*/^, \$metadata,
97 q^hlist_at_top^, \$hlist_at_top,
98 "allow_extra_options")) {
99
100 print STDERR "\nIncorrect options passed to $class, check your collect.cfg file\n";
101 $self->print_txt_usage(""); # Use default resource bundle
102 die "\n";
103
104 }
105
106 if (!$metadata) {
107 print STDERR "$class Error: required option -metadata not supplied\n";
108 $self->print_txt_usage(""); # Use default resource bundle
109
110 die "$class Error: required option -metadata not supplied\n";
111 }
112
113 if (!$hfile) {
114 print STDERR "$class Error: required option -hfile not supplied\n";
115 $self->print_txt_usage(""); # Use default resource bundle
116
117 die "$class Error: required option -hfile not supplied\n";
118 }
119
120 $title = $metadata unless ($title);
121 # if no sortname specified, it defaults to metadata
122 $sortname = $metadata unless ($sortname);
123 $sortname = undef if $sortname =~ /^nosort$/;
124 if (defined $sortname && $reverse_sort) {
125 $self->{'reverse_sort'} = 1;
126 }
127
128 my $subjectfile;
129 $subjectfile = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},"etc", $hfile);
130 if (!-e $subjectfile) {
131 my $collfile = $subjectfile;
132 $subjectfile = &util::filename_cat($ENV{'GSDLHOME'},"etc", $hfile);
133 if (!-e $subjectfile) {
134 my $outhandle = $self->{'outhandle'};
135 print STDERR "\nHierarchy Error: Can't locate subject file $hfile\n";
136 print STDERR "This file should be in $collfile or $subjectfile\n";
137 $self->print_txt_usage(""); # Use default resource bundle
138 print STDERR "\nHierarchy Error: Can't locate subject file $hfile\n";
139 print STDERR "This file should be in $collfile or $subjectfile\n";
140 die "\n";
141 }
142 }
143
144 $self->{'descriptorlist'} = {}; # first field in subject file
145 $self->{'locatorlist'} = {}; # second field in subject file
146 $self->{'subjectfile'} = $subjectfile;
147 $self->{'metaname'} = $metadata;
148 $self->{'sortname'} = $sortname;
149 $self->{'title'} = $title;
150 $self->{'hlist_at_top'} = $hlist_at_top;
151
152 return bless $self, $class;
153}
154
155sub init {
156 my $self = shift (@_);
157
158 # read in the subject file
159 my $list = &cfgread::read_cfg_file ($self->{'subjectfile'}, undef, '^[^#]?\S');
160 # $list is a hash that is indexed by the descriptor. The contents of this
161 # hash is a list of two items. The first item is the OID and the second item
162 # is the title
163 foreach $descriptor (keys (%$list)) {
164 $self->{'descriptorlist'}->{$descriptor} = $list->{$descriptor}->[0];
165 unless (defined $self->{'locatorlist'}->{$list->{$descriptor}->[0]}) {
166 $self->{'locatorlist'}->{$list->{$descriptor}->[0]}->{'title'} = $list->{$descriptor}->[1];
167 $self->{'locatorlist'}->{$list->{$descriptor}->[0]}->{'contents'} = [];
168 }
169 }
170}
171
172sub classify {
173 my $self = shift (@_);
174 my ($doc_obj) = @_;
175
176 my $doc_OID = $doc_obj->get_OID();
177
178 my $metadata = $doc_obj->get_metadata ($doc_obj->get_top_section(),
179 $self->{'metaname'});
180
181 my $lang = $doc_obj->get_metadata_element ($doc_obj->get_top_section(), 'Language');
182 $lang = 'en' unless defined $lang;
183
184 my $sortmeta = "";
185 if (defined $self->{'sortname'}) {
186 if ($self->{'sortname'} =~ /^filename$/i) {
187 $sortmeta = $doc_obj->get_source_filename();
188 } else {
189 $sortmeta = $doc_obj->get_metadata_element($doc_obj->get_top_section(),
190 $self->{'sortname'});
191 if (defined $sortmeta) {
192 if ($self->{'sortname'} eq "Creator") {
193 if ($lang eq 'en') {
194 &sorttools::format_string_name_english (\$sortmeta);
195 }
196 } else {
197 if ($lang eq 'en') {
198 &sorttools::format_string_english (\$sortmeta);
199 }
200 }
201 }
202 }
203 $sortmeta = "" unless defined $sortmeta;
204 }
205
206 foreach $metaelement (@$metadata) {
207 if ((defined $self->{'descriptorlist'}->{$metaelement}) &&
208 (defined $self->{'locatorlist'}->{$self->{'descriptorlist'}->{$metaelement}})) {
209 push (@{$self->{'locatorlist'}->{$self->{'descriptorlist'}->{$metaelement}}->{'contents'}},
210 [$doc_OID, $sortmeta]);
211 my $localid = $self->{'descriptorlist'}->{$metaelement};
212 my $classid = $self->get_number();
213
214 $doc_obj->add_metadata($doc_obj->get_top_section(), "memberof", "CL$classid.$localid");
215 }
216 }
217}
218
219sub get_classify_info {
220 my $self = shift (@_);
221
222 my $list = $self->{'locatorlist'};
223
224 my ($classifyinfo);
225 if ($self->{'hlist_at_top'}) {
226 $classifyinfo = $self->get_entry ($self->{'title'}, "HList", "Invisible");
227 } else {
228 $classifyinfo = $self->get_entry ($self->{'title'}, "VList", "Invisible");
229 }
230 # sorted the keys - otherwise funny things happen - kjdon 03/01/03
231 foreach $OID (sort keys (%$list)) {
232 my $tempinfo = $self->get_OID_entry ($OID, $classifyinfo, $list->{$OID}->{'title'}, "VList");
233
234 if (defined $self->{'sortname'}) {
235 if ($self->{'reverse_sort'}) {
236 foreach $subOID (sort {$b->[1] cmp $a->[1];} @{$list->{$OID}->{'contents'}}) {
237 push (@{$tempinfo->{'contains'}}, {'OID'=>$subOID->[0]});
238 }
239 } else {
240 foreach $subOID (sort {$a->[1] cmp $b->[1];} @{$list->{$OID}->{'contents'}}) {
241 push (@{$tempinfo->{'contains'}}, {'OID'=>$subOID->[0]});
242 }
243 } else {
244 foreach $subOID (@{$list->{$OID}->{'contents'}}) {
245 push (@{$tempinfo->{'contains'}}, {'OID'=>$subOID->[0]});
246 }
247 }
248 }
249
250 return $classifyinfo;
251}
252
253sub supports_memberof {
254 my $self = shift(@_);
255
256 return "true";
257}
258
259sub get_OID_entry {
260 my $self = shift (@_);
261 my ($OID, $classifyinfo, $title, $classifytype) = @_;
262
263 $OID = "" unless defined $OID;
264 $OID =~ s/^\.+//;
265
266 my ($headOID, $tailOID) = $OID =~ /^(\d+)(.*)$/;
267 $tailOID = "" unless defined $tailOID;
268
269 if (!defined $headOID) {
270 $classifyinfo->{'Title'} = $title;
271 $classifyinfo->{'classifytype'} = $classifytype;
272 return $classifyinfo;
273 }
274
275 $classifyinfo->{'contains'} = [] unless defined $classifyinfo->{'contains'};
276 my $offset = 0;
277 foreach my $thing (@{$classifyinfo->{'contains'}}) {
278 $offset ++ if defined $thing->{'OID'};
279 }
280
281 while (scalar(@{$classifyinfo->{'contains'}}) < ($headOID+$offset)) {
282 push (@{$classifyinfo->{'contains'}}, $self->get_entry("", $classifytype));
283 }
284
285 return $self->get_OID_entry ($tailOID, $classifyinfo->{'contains'}->[($headOID+$offset-1)], $title, $classifytype);
286}
287
288sub get_entry {
289 my $self = shift (@_);
290 my ($title, $childtype, $thistype) = @_;
291 my $memberof = &supports_memberof();
292
293 # organise into classification structure
294 my %classifyinfo = ('childtype'=>$childtype,
295 'Title'=>$title,
296 'supportsmemberof'=>$memberof,
297 'contains'=>[]);
298 $classifyinfo{'thistype'} = $thistype
299 if defined $thistype && $thistype =~ /\w/;
300
301 return \%classifyinfo;
302}
303
304
3051;
Note: See TracBrowser for help on using the repository browser.