File Coverage

blib/lib/Metadata/IAFA.pm
Criterion Covered Total %
statement 73 141 51.7
branch 24 80 30.0
condition 4 15 26.6
subroutine 11 19 57.8
pod 14 15 93.3
total 126 270 46.6


line stmt bran cond sub pod time code
1             # Hey emacs, this is -*-perl-*- !
2             #
3             # $Source: /home/cmdjb/develop/perl/Metadata/lib/Metadata/RCS/IAFA.pm,v $
4             #
5             # $Id: IAFA.pm,v 1.10 2001/01/09 12:07:26 cmdjb Exp $
6             #
7             # Metadata::IAFA - IAFA templates class
8             #
9             # Copyright (C) 1997-1998 Dave Beckett. All rights reserved.
10             #
11             # This module is free software; you can redistribute it and/or modify
12             # it under the same terms as Perl itself.
13             #
14              
15             package Metadata::IAFA;
16              
17             require 5.004;
18              
19 2     2   16381 use strict;
  2         4  
  2         97  
20 2         234 use vars qw(@ISA $VERSION $Debug %Default_Options
21 2     2   11 $HEADER_TEMPLATE_TYPE $FOOTER_TEMPLATE_TYPE);
  2         4  
22              
23 2     2   9 use Carp;
  2         4  
  2         151  
24              
25 2     2   1047 use Metadata::Base;
  2         6  
  2         6112  
26              
27             @ISA = qw( Metadata::Base );
28             $VERSION = sprintf("%d.%02d", ('$Revision: 1.10 $ ' =~ /\$Revision:\s+(\d+)\.(\d+)/));
29              
30             %Default_Options=(
31             TEMPLATE_TYPE => 'DOCUMENT',
32             STRICT => '0',
33             DEBUG => '0',
34             WRAP => '0',
35             );
36              
37             $HEADER_TEMPLATE_TYPE = 'X-AFA-HEADER';
38             $FOOTER_TEMPLATE_TYPE = 'X-AFA-FOOTER';
39              
40              
41             # Class debugging
42             $Debug = 0;
43              
44             sub debug {
45 0     0 1 0 my $self=shift;
46             # Object debug - have an object reference
47 0 0       0 if (ref ($self)) {
48 0         0 my $old=$self->{DEBUG};
49 0 0       0 $self->{DEBUG}=@_ ? shift : 1;
50 0         0 $self->SUPER::debug($self->{DEBUG});
51 0         0 return $old;
52             }
53              
54             # Class debug (self is debug level)
55 0 0       0 return $Debug if !defined $self; # Careful, could be debug(0)
56              
57 0         0 my $old=$Debug;
58 0         0 $Default_Options{DEBUG}=$Debug=$self;
59 0         0 Metadata::Base::debug($Debug);
60 0         0 $old;
61             }
62              
63 0     0 0 0 sub whowasi { (caller(1))[3] }
64              
65              
66             # Constructor
67             sub new {
68 3     3 1 1546 my $proto =shift;
69 3   33     31 my $class = ref($proto) || $proto;
70 3         12 my $options= { @_ };
71 3         13 $options->{ORDERED}=1;
72 3         20 for (keys %Default_Options) {
73 12 50       64 $options->{$_}=$Default_Options{$_} unless defined $options->{$_};
74             }
75              
76 3         37 my $self = $class->SUPER::new($options);
77 3         10 bless $self, $class;
78 3         24 return $self;
79             }
80              
81              
82             # Clone
83             sub clone ($) {
84 0     0 1 0 my $self=shift;
85              
86 0         0 my $copy = $self->SUPER::clone;
87              
88 0         0 $copy->{TEMPLATE_TYPE}= $self->{TEMPLATE_TYPE};
89              
90 0         0 $copy;
91             }
92              
93              
94             sub template_type ($;$) {
95 0     0 1 0 my $self=shift;
96 0 0       0 return $self->{TEMPLATE_TYPE} if !@_;
97              
98 0         0 my $old=$self->{TEMPLATE_TYPE};
99 0         0 $self->{TEMPLATE_TYPE}=shift;
100 0         0 $old;
101             }
102              
103              
104             # Set the given element, value and index?
105             sub validate ($$$;$) {
106 8     8 1 45 my($self, $element, $value, $index)=@_;
107 8 0       35 warn "@{[&whowasi]}: Field: $element Value: ", (defined $value) ? $value : "(undefined)", " Index:",(defined $index) ? $index : "(undefined)", "\n" if $self->{DEBUG};
  0 0       0  
    50          
108 8 100       30 if ($element eq 'Template-Type') {
109 1         6 $self->{TEMPLATE_TYPE}=$value;
110 1         7 return;
111             }
112 7 100       55 $index=$1 if $element =~ s/-v(\d+)$//;
113 7         40 return ($element, $value, $index);
114             }
115              
116              
117             # Check the legality of the given element and index
118             sub validate_elements ($$;$) {
119 14     14 1 63 my($self, $element, $index)=@_;
120 14 0       39 warn "@{[&whowasi]}: Field: $element Index:", (defined $index) ? $index : "(undefined)", "\n" if $self->{DEBUG};
  0 50       0  
121            
122 14 100       67 $index=$1 if $element =~ s/-v(\d+)$//;
123 14         63 return ($element, $index);
124             }
125              
126              
127             sub read ($$) {
128 1     1 1 126 my $self = shift;
129 1         4 my $fh=shift;
130              
131 1         19 $self->clear;
132              
133 1 50       22 return undef if eof($fh);
134              
135 1         3 my $element='';
136 1         3 my $value='';
137 1         3 my $count=0;
138 1         10 while(<$fh>) {
139 4         9 chomp;
140 4 50       45 if (/^([-#\w]+):\s*(.*)$/) {
    0          
    0          
141 4         21 my($new_attr,$new_value)=($1,$2);
142 4 100 33     29 $self->set($element, $value) and $count++ if $element;
143 4         8 $count++;
144 4         10 $element=$new_attr; $value=$new_value;
  4         35  
145             } elsif (/^\s+(.*)$/) { # Allow leading whitespace to continue line
146 0         0 my $bit=$1;
147              
148             # Strictly...
149 0 0 0     0 last if $self->{STRICT} && !$bit; # end on a blank line too
150              
151             # A continuation line, so what about that white space?
152 0 0       0 if ($value) {
153 0 0       0 if ($self->{STRICT}) {
154             # strict - remove in URI elements, otherwise collapse to ' '
155 0 0       0 if ($element !~ /URI$/) {
156 0         0 $value .= ' ';
157             }
158             } else {
159             # lax - preserve the newline, who cares?
160 0         0 $value.="\n";
161             }
162             }
163              
164 0         0 $value.=$bit;
165             } elsif (!$_) {
166 0         0 last;
167             } else {
168 0         0 warn "IAFA::read:$.: Do not understand line '$_'\n";
169             }
170             }
171            
172 1 50 33     12 $self->set($element, $value) and $count++ if $element;
173 1 50       9 warn "@{[&whowasi]}: Read $count elements\n" if $self->{DEBUG};
  0         0  
174 1         6 return 1;
175             }
176              
177              
178             sub format ($) {
179 1     1 1 398269 require 'Text/Wrap.pm';
180              
181 1         4297 my $self=shift;
182 1         8 my $string="Template-Type: $self->{TEMPLATE_TYPE}\n";
183 1         20 for my $element ($self->order) {
184 3         25 my $variants=$self->size($element);
185 3         6 my $variant=0;
186 3         15 for my $value ($self->get($element)) {
187 5 100       18 next unless defined $value;
188 3         9 chomp $value;
189 3 50       13 if ($self->{STRICT}) {
190 0         0 $value =~ s/\s+/ /g;
191             } else {
192 3         8 $value =~ s/\n/\n\t/g;
193             }
194 3 100       18 my $bit=($variants>1) ? "$element-v$variant: $value\n" : "$element: $value\n";
195 3 50 33     34 if ($self->{STRICT} || $self->{WRAP}) {
196 0         0 $bit=Text::Wrap::wrap("\t", "\t", $bit);
197             }
198              
199 3         10 $string.=$bit;
200             } continue {
201 5         22 $variant++;
202             }
203             }
204 1         9 $string;
205             }
206              
207              
208             sub pack ($) {
209 0     0 1 0 my $self=shift;
210 0         0 my $string=$self->SUPER::pack;
211              
212             # Use the knowledge that a field called Template-Type automagically becomes
213             # a Template Type, not a regular field (via validate method).
214             # Also depend on Metadata::Base using 'thing\0' too.
215 0         0 $string="Template-Type\0$self->{TEMPLATE_TYPE}\0".$string;
216              
217 0         0 $string;
218             }
219              
220             # Base version is fine
221             # sub unpack
222              
223              
224             sub get_date_as_seconds ($$) {
225 1     1 1 8 my($self,$element)=@_;
226              
227 1         5 my $value=$self->get($element);
228              
229 1 50       4 unless ($self->{STRICT}) {
230 1 50       13 return $value if $value =~ /^\d+$/;
231              
232 0 0       0 if (my($year,$month,$day)=($value=~ /^(\d\d\d\d)-(\d\d)-(\d\d)$/)) {
233 0         0 require 'Time/Local.pm';
234              
235 0         0 return Time::Local::timegm(0,0,0,$day,$month-1,$year-1900);
236             }
237             }
238              
239 0         0 require 'Date/Parse.pm';
240              
241 0         0 return Date::Parse::str2time($value);
242             }
243              
244              
245             sub set_date_as_seconds ($$$) {
246 1     1 1 16 my($self,$element,$value)=@_;
247              
248 1 50       5 if ($self->{STRICT}) {
249 0         0 require 'Date/Format.pm';
250              
251             # RFC Dow, day month year HH:MM TZ
252 0         0 $value=Date::Format::time2str("%a, %d %b %Y %T %z", $value);
253             }
254              
255 1         10 $self->set($element, $value);
256             }
257              
258              
259             sub decode_uri_element ($) {
260 0     0 1   my($uri)=@_;
261              
262 0 0         return (undef,undef,undef) if !defined($uri);
263              
264 0           my($path,$remotepath);
265 0 0         if ($uri =~ /^(.+)\s+->\s+(.+)$/) {
266 0           ($path,$remotepath)=($1,$2);
267             } else {
268 0           $path=$uri; $remotepath='';
  0            
269             }
270 0           my($basepath)='';
271             # URL: ://host/...
272 0 0         if ($path=~ m%^\w+://.+%) {
    0          
    0          
273 0           $basepath=$path; $remotepath=$path; $path='';
  0            
  0            
274             # Relative URL: /path/file
275             } elsif ($path=~ m%/([^/]+)$%) {
276 0           $basepath=$1;
277             # File: file
278             } elsif ($path !~ m%/%) {
279 0           $basepath=$path;
280             }
281              
282 0           return ($basepath, $path, $remotepath);
283             }
284              
285              
286             sub encode_uri_element ($;$) {
287 0     0 1   my($path, $remotepath)=@_;
288              
289 0 0         return $remotepath ? "$path -> $remotepath" : $path;
290             }
291              
292              
293             sub order_template_type ($) {
294 0     0 1   my($type)=@_;
295            
296 0 0         return 0 if $type eq $HEADER_TEMPLATE_TYPE;
297 0 0         return 2 if $type eq $FOOTER_TEMPLATE_TYPE;
298              
299 0           return 1;
300              
301             }
302              
303              
304              
305             1;
306             __END__