File Coverage

blib/lib/XML/Essex/Base.pm
Criterion Covered Total %
statement 66 73 90.4
branch 21 32 65.6
condition 5 11 45.4
subroutine 12 13 92.3
pod 6 6 100.0
total 110 135 81.4


line stmt bran cond sub pod time code
1             package XML::Essex::Base;
2              
3             $VERSION = 0.000_1;
4              
5             =head1 NAME
6              
7             XML::Essex::Base - class for Essex SAX components
8              
9             =head1 SYNOPSIS
10              
11             ## Not for external use.
12              
13             =head1 DESCRIPTION
14              
15             All Essex generators, filters and handlers must inherit from this
16             class among others. This class provides methods common to all
17             three and specialized export semantics so that exports may be
18             inherited from base classes.
19              
20             =for test_scripts XML-Generator-Essex.t XML-Filter-Essex.t
21              
22             =cut
23              
24 8     8   669 use strict;
  8         20  
  8         319  
25              
26 8     8   49 use Carp (); # keep from acquiring Croak's exported subs as methods.
  8         12  
  8         754  
27              
28             our $self;
29              
30             =head1 METHODS
31              
32             =over
33              
34             =cut
35              
36             =item new
37              
38             Creates and initializes an instance.
39              
40             =cut
41              
42             sub new {
43 1     1 1 261 my $proto = shift;
44 1   33     9 my $self = bless { @_ }, ref $proto || $proto;
45 1         7 $self->_init; ## These must use NEXT::, it's a diamond hierarchy at
46             ## times (eq XML::Filter::Dispatcher).
47 1         1812 return $self;
48             }
49              
50             sub _classes {
51 8     8   58 no strict "refs";
  8         17  
  8         835  
52 19 100   19   19 return ( $_ ) unless exists ${"${_}::"}{ISA};
  19         177  
53 9         14 return ( $_, map _classes( $_ ), @{"${_}::ISA"} );
  9         45  
54             }
55              
56             =item import
57              
58             Uses C<@EXPORT> and C<@EXPORT_OK> arrays like Exporter.pm, but
59             implements inheritence on it. Understands the meaning of the tags
60             ":all" and ":default", which are hardcoded (C<%EXPORT_TAGS> is ignored
61             thus far), but does not emulate Exporter's other, rarely used syntaxes.
62              
63             =cut
64              
65 8     8   45 use vars qw( $self );
  8         14  
  8         780  
66              
67             sub import {
68 8     8   6394 my $class = shift;
69 8         19 my $caller = caller;
70              
71 8         19 my $no_params = ! @_;
72              
73 8     8   40 no strict "refs";
  8         14  
  8         7726  
74              
75 8         13 my @classes = do {
76 8         15 local $_ = $class;
77 8         11 my %seen;
78 8         21 grep !$seen{$_}++, _classes;
79             };
80              
81 8         15 my %tags;
82 8 50       25 @_ = grep
83             substr( $_, 0, 1 ) eq ":" ? $tags{$_} = undef : 1,
84             @_;
85              
86 41         79 my %default_exports = (
87 19         70 map { ( $_ => undef ) }
88             map
89 9         56 exists ${"${_}::"}{EXPORT}
90 8 100       14 ? @{"${_}::EXPORT"}
91             : (),
92             @classes
93             );
94              
95 8 100       37 push @_, keys %default_exports if exists $tags{":default"};
96              
97 4         10 my %all_exports = (
98             %default_exports,
99             ( exists $tags{":all"} || @_ )
100             ? (
101 6         24 map { ( $_ => undef ) }
102             map
103 4         12 exists ${"${_}::"}{EXPORT_OK}
104 8 100 100     76 ? @{"${_}::EXPORT_OK"}
    100          
105             : (),
106             @classes
107             )
108             : ()
109             );
110 8 100       28 push @_, keys %all_exports if exists $tags{":all"};
111              
112 8 100       36 @_= keys %default_exports if $no_params;
113              
114 8         13 my @not_exported;
115              
116             my %seen;
117 8         43 for ( grep !$seen{$_}++, @_ ) {
118 43 50       100 unless ( exists $all_exports{$_} ) {
119 0         0 push @not_exported, $_;
120 0         0 next;
121             }
122              
123 43   50     217 *{"${caller}::$_"} = ( $class->can( $_ ) || \&{"${class}::$_"} );
  43         198  
124             }
125              
126             Carp::croak
127 8 50       4875 "functions ",
128             join( " ", @not_exported ),
129             " not exported by $class"
130             if @not_exported;
131             }
132              
133             =item main
134              
135             The main routine. Overload this or pass in a code ref
136             to C \&foo )> or C to set this.
137              
138             =cut
139              
140             sub main {
141 1     1 1 3 goto &{$_[0]->{Main}};
  1         8  
142             }
143              
144             =item set_main
145              
146             Sets the main routines to a code reference.
147              
148             =cut
149              
150             sub set_main {
151 1     1 1 1259 my $self = shift;
152 1         4 $self->{Main} = shift;
153             }
154              
155             =item reset
156              
157             Called before the main routine is called.
158              
159             =cut
160              
161             sub reset {
162 1     1 1 164 my $self = shift;
163              
164 1         3 $self->{NamespaceMaps} = [];
165              
166 1         17 $self->NEXT::reset;
167             }
168              
169             =item finish
170              
171             Called after the main routine is called.
172              
173             =cut
174              
175             =item execute
176              
177             Prepares the runtime environment, calls C<<$self->main( @_ )>>, cleans
178             up afterwards and runs sanity checks.
179              
180             This is called automatically in filters and handlers, must be
181             called manually in generators.
182              
183             Calls reset() before and finish() after main().
184              
185             =cut
186              
187             sub execute {
188 1     1 1 312 local $self = shift;
189              
190 1 50       5 return if $self->{NoExecute}; ## Used by XML::Essex
191              
192             ## Don't save a reference to the output_monitor in case some whacko
193             ## manages to alter $self->{Handler} somehow.
194 1         6 $self->reset;
195              
196 1         100 local $_; ## get() explicitly sets $_ for the convenience of
197             ## main() programmers. In unthreaded mode, we want
198             ## to be sure not to perturb the caller's sense of $_.
199              
200 1         2 my $r;
201             my @r;
202 1         2 my $ok = eval {
203             wantarray
204 1 50       21 ? @r = $self->main( @_ )
    50          
205             : defined wantarray
206             ? $r = $self->main( @_ )
207             : $self->main( @_ );
208 1         47 1;
209             };
210              
211 1         6 my ( $result_set, $result ) = $self->finish( $ok, $@ );
212              
213 1 50       6 return $result if $result_set;
214 0 0         return wantarray ? @r : $r;
215             }
216              
217              
218             =item namespace_map
219              
220             aka: ns_map
221              
222             $self->ns_map(
223             $ns1 => $prefix1,
224             $ns2 => $prefix2,
225             ...
226             );
227              
228             Creates a new set of mappings in addition to any that are already in
229             effect. If a namespace is mapped to multiple prefixes, the last one
230             created is used. The mappings stay in effect until the map objected
231             referred to by C<$map> is destroyed.
232              
233             NOTE: the namespace prefixes from the source document override the
234             namespace prefixes set here when events are transmitted downstream.
235             This is so that namespace prefixes are not altered arbitrarily; the
236             philosophy is to make as few changes to the source document as possible
237             and remapping prefixes to match what happens to be declared in the
238             filter would not be proper.
239              
240             For names in namespaces that are introduced by the filter and are not in
241             the source document, the prefixes from the filter are used. This is a
242             bit dangerous: some other namespace in the source document may use the
243             same prefix and the result could be catastrophic. Some future version
244             will try to detect these collisions, and there may even be a nice way to
245             avoid them.
246              
247             Source document prefixes are generally invisible in the Essex
248             environment (aside from the start_prefix_mapping and end_prefix_mapping
249             events) because they could be anything. If you root around inside essex
250             objects enough, though, you can ferret them out. Trying to do that is a
251             pretty good indication that something's wrong.
252              
253             =cut
254              
255             sub namespace_map {
256 0 0 0 0 1   local $self = shift if @_ && UNIVERSAL::isa( $_[0], __PACKAGE__ );
257 0           require XML::Essex::NamespaceMap;
258 0           push @{$self->{Namespaces}},
  0            
259             XML::Essex::NamespaceMap->new( $self, @_ );
260             }
261              
262             *ns_map = \&namespace_map;
263              
264              
265             =back
266              
267             =head1 LIMITATIONS
268              
269             Does not support other Exporter features like exporting past several calling
270             modules.
271              
272             =head1 COPYRIGHT
273              
274             Copyright 2002, R. Barrie Slaymaker, Jr., All Rights Reserved
275              
276             =head1 LICENSE
277              
278             You may use this module under the terms of the BSD, Artistic, oir GPL licenses,
279             any version.
280              
281             =head1 AUTHOR
282              
283             Barrie Slaymaker
284              
285             =cut
286              
287             1;