source: trunk/gsdl/perllib/classify/AZList.pm@ 425

Last change on this file since 425 was 409, checked in by sjboddie, 25 years ago

Tidied things up a bit

  • Property svn:keywords set to Author Date Id Revision
File size: 5.4 KB
Line 
1# classifier plugin for sorting alphabetically
2
3package AZList;
4
5use sorttools;
6
7sub new {
8 my ($class, @options) = @_;
9
10 if (!defined @options || !scalar @options) {
11 die "AZList used with no metadata name to classify by\n";
12 }
13
14 return bless {
15 'list'=>{},
16 'metaname' => $options[0]
17 }, $class;
18}
19
20sub init {
21 my $self = shift (@_);
22
23 $self->{'list'} = {};
24}
25
26sub classify {
27 my $self = shift (@_);
28 my ($doc_obj) = @_;
29
30 my $doc_OID = $doc_obj->get_OID();
31 my $metavalue = $doc_obj->get_metadata_element ($doc_obj->get_top_section(),
32 $self->{'metaname'});
33
34 # if this document doesn't contain the metadata element we're
35 # sorting by we won't include it in this classification
36 if (defined $metavalue && $metavalue =~ /\w/) {
37 if ($self->{'metaname'} eq 'Creator') {
38 &sorttools::format_string_name_english (\$metavalue);
39 } else {
40 &sorttools::format_string_english (\$metavalue);
41 }
42 if (defined $self->{'list'}->{$doc_OID}) {
43 print STDERR "WARNING: AZList::classify called multiple times for $doc_OID\n";
44 }
45 $self->{'list'}->{$doc_OID} = $metavalue;
46 }
47}
48
49sub get_classify_info {
50 my $self = shift (@_);
51
52 my @classlist = sort {$self->{'list'}->{$a} cmp $self->{'list'}->{$b};} keys %{$self->{'list'}};
53
54 return $self->splitlist (\@classlist);
55}
56
57sub get_entry {
58 my $self = shift (@_);
59 my ($title, $classifytype) = @_;
60
61 # organise into classification structure
62 my %classifyinfo = ('classifytype'=>$classifytype,
63 'Title'=>$title,
64 'contains'=>[]);
65
66 return \%classifyinfo;
67}
68
69# splitlist takes an ordered list of classifications (@$classlistref) and splits it
70# up into alphabetical sub-sections.
71sub splitlist {
72 my $self = shift (@_);
73 my ($classlistref) = @_;
74 my $classhash = {};
75
76 # top level
77 my $classifyinfo = $self->get_entry ($self->{'metaname'}, "AZList");
78
79 # don't need to do any splitting if there are less than 20 classifications
80 if ((scalar @$classlistref) <= 20) {
81 foreach $subOID (@$classlistref) {
82 push (@{$classifyinfo->{'contains'}}, {'OID'=>$subOID});
83 }
84 return $classifyinfo;
85 }
86
87 # first split up the list into separate A-Z and 0-9 classifications
88 foreach $classification (@$classlistref) {
89 my $title = $self->{'list'}->{$classification};
90 $title =~ s/^(.).*$/$1/;
91 $title =~ tr/[a-z]/[A-Z]/;
92 if ($title =~ /^[0-9]$/) {$title = '0-9';}
93 elsif ($title !~ /^[A-Z]$/) {
94 print STDERR "AZList: WARNING $classification has badly formatted title ($title)\n";
95 }
96 $classhash->{$title} = [] unless defined $classhash->{$title};
97 push (@{$classhash->{$title}}, $classification);
98 }
99 $classhash = $self->compactlist ($classhash);
100
101 my @tmparr = ();
102 foreach $subsection (sort keys (%$classhash)) {
103 push (@tmparr, $subsection);
104 }
105
106 # if there's a 0-9 section it will have been sorted to the beginning
107 # but we want it at the end
108 if ($tmparr[0] eq '0-9') {
109 shift @tmparr;
110 push (@tmparr, '0-9');
111 }
112
113 foreach $subclass (@tmparr) {
114 my $tempclassify = $self->get_entry($subclass, "AZList");
115 foreach $subsubOID (@{$classhash->{$subclass}}) {
116 push (@{$tempclassify->{'contains'}}, {'OID'=>$subsubOID});
117 }
118 push (@{$classifyinfo->{'contains'}}, $tempclassify);
119 }
120
121 return $classifyinfo;
122}
123
124sub compactlist {
125 my $self = shift (@_);
126 my ($classhashref) = @_;
127 my $compactedhash = {};
128 my @currentOIDs = ();
129 my $currentfirstletter = "";
130 my $currentlastletter = "";
131 my $lastkey = "";
132
133 # minimum and maximum documents to be displayed per page.
134 # the actual maximum will be max + (min-1).
135 # the smallest sub-section is a single letter at present
136 # so in this case there may be many times max documents
137 # displayed on a page.
138 my $min = 10;
139 my $max = 30;
140
141 foreach $subsection (sort keys %$classhashref) {
142 if ($subsection eq '0-9') {
143 @{$compactedhash->{$subsection}} = @{$classhashref->{$subsection}};
144 next;
145 }
146 $currentfirstletter = $subsection if $currentfirstletter eq "";
147 if ((scalar (@currentOIDs) < $min) ||
148 ((scalar (@currentOIDs) + scalar (@{$classhashref->{$subsection}})) <= $max)) {
149 push (@currentOIDs, @{$classhashref->{$subsection}});
150 $currentlastletter = $subsection;
151 } else {
152
153 if ($currentfirstletter eq $currentlastletter) {
154 @{$compactedhash->{$currentfirstletter}} = @currentOIDs;
155 $lastkey = $currentfirstletter;
156 } else {
157 @{$compactedhash->{"$currentfirstletter-$currentlastletter"}} = @currentOIDs;
158 $lastkey = "$currentfirstletter-$currentlastletter";
159 }
160 if (scalar (@{$classhashref->{$subsection}}) >= $max) {
161 $compactedhash->{$subsection} = $classhashref->{$subsection};
162 @currentOIDs = ();
163 $currentfirstletter = "";
164 } else {
165 @currentOIDs = @{$classhashref->{$subsection}};
166 $currentfirstletter = $subsection;
167 $currentlastletter = $subsection;
168 }
169 }
170 }
171
172 # add final OIDs to last sub-classification if there aren't many otherwise
173 # add final sub-classification
174 if (scalar (@currentOIDs) < $min) {
175 my ($newkey) = $lastkey =~ /^(.)/;
176 @currentOIDs = (@{$compactedhash->{$lastkey}}, @currentOIDs);
177 delete $compactedhash->{$lastkey};
178 @{$compactedhash->{"$newkey-$currentlastletter"}} = @currentOIDs;
179 } else {
180 if ($currentfirstletter eq $currentlastletter) {
181 @{$compactedhash->{$currentfirstletter}} = @currentOIDs;
182 } else {
183 @{$compactedhash->{"$currentfirstletter-$currentlastletter"}} = @currentOIDs;
184 }
185 }
186
187 return $compactedhash;
188}
189
1901;
Note: See TracBrowser for help on using the repository browser.