File Coverage

blib/lib/XML/Filter/Merger.pm
Criterion Covered Total %
statement 82 90 91.1
branch 22 24 91.6
condition 17 21 80.9
subroutine 16 21 76.1
pod 13 13 100.0
total 150 169 88.7


line stmt bran cond sub pod time code
1             package XML::Filter::Merger;
2             {
3             $XML::Filter::Merger::VERSION = '0.46';
4             }
5              
6             # ABSTRACT: Assemble multiple SAX streams in to one document
7              
8              
9 7     7   170458 use base qw( XML::SAX::Base );
  7         16  
  7         722  
10              
11 7     7   39 use strict;
  7         15  
  7         219  
12 7     7   37 use Carp;
  7         14  
  7         486  
13 7     7   1283 use XML::SAX::EventMethodMaker qw( sax_event_names compile_missing_methods );
  7         18  
  7         8264  
14              
15             sub _logging() { 0 };
16              
17              
18             sub new {
19 9     9 1 2225 my $self = shift->SUPER::new( @_ );
20 9         633 $self->reset;
21 9         27 return $self;
22             }
23              
24              
25             sub reset {
26 19     19 1 45 my $self = shift;
27 19         41 $self->{DocumentDepth} = 0;
28 19         39 $self->{DocumentCount} = 0;
29 19         35 $self->{TailEvents} = undef;
30 19         40 $self->{ManifoldDocumentStarted} = 0;
31 19         32 $self->{Cutting} = 0;
32 19         38 $self->{Depth} = 0;
33 19         33 $self->{RootEltSeen} = 0;
34 19         38 $self->{AutoReset} = 0;
35             }
36              
37              
38             sub start_manifold_document {
39 8     8 1 502 my $self = shift;
40 8         30 $self->reset;
41 8         18 $self->{ManifoldDocumentStarted} = 1;
42              
43             ## A little fudging here until XML::SAX::Base gets a new release
44 8         28 $self->{Methods} = {};
45             }
46              
47              
48             sub _log {
49 0     0   0 my $self = shift;
50              
51 0         0 warn "MERGER: ",
52             $self->{DocumentCount}, " ",
53             "| " x $self->{DocumentDepth},
54             ". " x $self->{Depth},
55             @_,
56             "\n";
57             }
58              
59              
60             sub _cutting {
61 183     183   220 my $self = shift;
62              
63             # if ( @_ ) {
64             # my $v = shift;
65             #warn "MERGER: CUTTING ", $v ? "SET!!" : "CLEARED!!", "\n"
66             # if ( $v && ! $self->{Cutting} ) || ( ! $v && $self->{Cutting} );
67             # $self->{Cutting} = $v;
68             # }
69              
70 183         213 my $v = shift;
71              
72 183 100 100     1394 $v = 1
      66        
      100        
73             if ! defined $v
74             && ( $self->{DocumentCount} > 1
75             || $self->{DocumentDepth} > 1
76             )
77             && ! $self->{Depth};
78              
79              
80             $self->_log(
81             $v ? () : "NOT ",
82             "CUTTING ",
83 183         190 do { my $c = (caller(1))[3]; $c =~ s/.*:://; $c },
84             " (doccount=$self->{DocumentCount}",
85             " docdepth=$self->{DocumentDepth}",
86             " depth=$self->{Depth})"
87             ) if _logging;
88 183         1907 return $v;
89              
90 0         0 return $self->{Cutting};
91             }
92              
93              
94             sub _saving {
95 85     85   109 my $self = shift;
96              
97             return
98 85   100     2556 $self->{ManifoldDocumentStarted}
99             && $self->{DocumentCount} == 1
100             && $self->{DocumentDepth} == 1
101             && $self->{RootEltSeen};
102             }
103              
104              
105             sub _push {
106 18     18   30 my $self = shift;
107              
108 18         31 $self->_log( "SAVING ", $_[0] ) if _logging;
109              
110 18         25 push @{$self->{TailEvents}}, [ @_ ];
  18         62  
111              
112 18         53 return undef;
113             }
114              
115              
116             sub start_document {
117 29     29 1 792 my $self = shift;
118              
119 29 50       100 $self->reset if $self->{AutoReset};
120              
121 29         40 push @{$self->{DepthStack}}, $self->{Depth};
  29         78  
122              
123 29 100       109 ++$self->{DocumentCount} unless $self->{DocumentDepth};
124 29         47 ++$self->{DocumentDepth};
125 29         183 $self->{Depth} = 0;
126              
127 29 100       71 $self->SUPER::start_document( @_ )
128             unless $self->_cutting;
129              
130             }
131              
132             sub end_document {
133 29     29 1 1340 my $self = shift;
134              
135 29         38 my $r;
136              
137 29 100       60 unless ( $self->_cutting ) {
138 11 100       26 if ( $self->_saving ) {
139 8         23 $self->_push( "end_document", @_ );
140             }
141             else {
142 3         12 $r = $self->SUPER::end_document( @_ );
143             }
144             }
145              
146 29         632 --$self->{DocumentDepth};
147 29         37 $self->{Depth} = pop @{$self->{DepthStack}};
  29         61  
148              
149 29         181 return $r;
150             }
151              
152              
153             sub start_element {
154 41     41 1 9502 my $self = shift ;
155              
156 41         53 my $r;
157              
158 41 100       144 $r = $self->SUPER::start_element( @_ )
    100          
159             unless $self->_cutting( $self->{IncludeAllRoots} ? 0 : () );
160              
161 41         3369 ++$self->{Depth};
162              
163 41         126 return $r;
164             }
165              
166              
167             sub end_element {
168 41     41 1 2624 my $self = shift ;
169              
170 41         65 --$self->{Depth};
171 41   100     256 $self->{RootEltSeen} ||= $self->{DocumentDepth} == 1 && $self->{Depth} == 0;
      100        
172              
173 41 100       130 return undef if $self->_cutting( $self->{IncludeAllRoots} ? 0 : () );
    100          
174              
175 35 100       91 return $self->_saving
176             ? $self->_push( "end_element", @_ )
177             : $self->SUPER::end_element( @_ );
178             }
179              
180             compile_missing_methods __PACKAGE__, <<'TEMPLATE_END', sax_event_names;
181             sub {
182             my $self = shift;
183              
184             return undef if $self->_cutting;
185              
186             return $self->_saving
187             ? $self->_push( "", @_ )
188             : $self->SUPER::( @_ );
189             }
190             TEMPLATE_END
191              
192              
193             sub in_master_document {
194 0     0 1 0 my $self = shift;
195              
196 0   0     0 return $self->{DocumentCount} == 1 && $self->{DocumentDepth} <= 1;
197             }
198              
199              
200             sub document_depth {
201 0     0 1 0 shift->{DocumentDepth} - 1;
202             }
203              
204              
205              
206              
207             sub element_depth {
208 0     0 1 0 shift->{Depth} - 1;
209             }
210              
211              
212              
213             sub top_level_document_number {
214 0     0 1 0 shift->{DocumentCount} - 1;
215             }
216              
217              
218              
219              
220              
221              
222             sub end_manifold_document {
223 8     8 1 28 my $self = shift;
224              
225 8         13 my $r;
226 8 50       29 if ( $self->{TailEvents} ) {
227 8         17 for ( @{$self->{TailEvents}} ) {
  8         24  
228 18         705 my $sub_name = shift @$_;
229 18         25 $self->_log( "PLAYING BACK $sub_name" ) if _logging;
230 18         35 $sub_name = "SUPER::$sub_name";
231 18         92 $r = $self->$sub_name( @$_ );
232             }
233             }
234 8         607 $self->{ManifoldDocumentStarted} = 0;
235 8         15 $self->{AutoReset} = 1;
236 8         117 return $r;
237             }
238              
239              
240             sub set_include_all_roots {
241 8     8 1 1117 my $self = shift;
242 8         24 $self->{IncludeAllRoots} = shift;
243             }
244              
245              
246             1;
247              
248             __END__