File Coverage

blib/lib/Object/Pluggable/Pipeline.pm
Criterion Covered Total %
statement 67 200 33.5
branch 15 92 16.3
condition 0 4 0.0
subroutine 12 22 54.5
pod 13 13 100.0
total 107 331 32.3


line stmt bran cond sub pod time code
1             package Object::Pluggable::Pipeline;
2             BEGIN {
3 2     2   3160 $Object::Pluggable::Pipeline::AUTHORITY = 'cpan:HINRIK';
4             }
5             BEGIN {
6 2     2   36 $Object::Pluggable::Pipeline::VERSION = '1.29';
7             }
8              
9 2     2   12 use strict;
  2         4  
  2         55  
10 2     2   9 use warnings;
  2         4  
  2         43  
11 2     2   10 use Carp;
  2         11  
  2         127  
12 2     2   11 use Scalar::Util qw(weaken);
  2         4  
  2         4756  
13              
14             sub new {
15 1     1 1 2 my ($package, $pluggable) = @_;
16              
17 1         8 my $self = bless {
18             PLUGS => {},
19             PIPELINE => [],
20             HANDLES => {},
21             OBJECT => $pluggable,
22             }, $package;
23              
24 1         9 weaken($self->{OBJECT});
25              
26 1         4 return $self;
27             }
28              
29             sub push {
30 1     1 1 4 my ($self, $alias, $plug, @register_args) = @_;
31              
32 1 50       5 if ($self->{PLUGS}{$alias}) {
33 0         0 $@ = "Plugin named '$alias' already exists ($self->{PLUGS}{$alias})";
34 0         0 return;
35             }
36              
37 1         6 my $return = $self->_register($alias, $plug, @register_args);
38 1 50       4 return if !$return;
39              
40 1         2 push @{ $self->{PIPELINE} }, $plug;
  1         3  
41 1         3 return scalar @{ $self->{PIPELINE} };
  1         4  
42             }
43              
44             sub pop {
45 0     0 1 0 my ($self, @unregister_args) = @_;
46              
47 0 0       0 return if !@{ $self->{PIPELINE} };
  0         0  
48              
49 0         0 my $plug = pop @{ $self->{PIPELINE} };
  0         0  
50 0         0 my $alias = $self->{PLUGS}{$plug};
51 0         0 $self->_unregister($alias, $plug, @unregister_args);
52              
53 0 0       0 return wantarray ? ($plug, $alias) : $plug;
54             }
55              
56             sub unshift {
57 0     0 1 0 my ($self, $alias, $plug, @register_args) = @_;
58              
59 0 0       0 if ($self->{PLUGS}{$alias}) {
60 0         0 $@ = "Plugin named '$alias' already exists ($self->{PLUGS}{$alias}";
61 0         0 return;
62             }
63              
64 0         0 my $return = $self->_register($alias, $plug, @register_args);
65 0 0       0 return if !$return;
66              
67 0         0 unshift @{ $self->{PIPELINE} }, $plug;
  0         0  
68 0         0 return scalar @{ $self->{PIPELINE} };
  0         0  
69             }
70              
71             sub shift {
72 0     0 1 0 my ($self, @unregister_args) = @_;
73              
74 0 0       0 return if !@{ $self->{PIPELINE} };
  0         0  
75              
76 0         0 my $plug = shift @{ $self->{PIPELINE} };
  0         0  
77 0         0 my $alias = $self->{PLUGS}{$plug};
78 0         0 $self->_unregister($alias, $plug, @unregister_args);
79              
80 0 0       0 return wantarray ? ($plug, $alias) : $plug;
81             }
82              
83             sub replace {
84 0     0 1 0 my ($self, $old, $new_a, $new_p, $unregister_args, $register_args) = @_;
85            
86 0 0       0 my ($old_a, $old_p) = ref $old
87             ? ($self->{PLUGS}{$old}, $old)
88             : ($old, $self->{PLUGS}{$old})
89             ;
90              
91 0 0       0 if (!$old_p) {
92 0         0 $@ = "Plugin '$old_a' does not exist";
93 0         0 return;
94             }
95              
96             $self->_unregister(
97 0 0       0 $old_a,
98             $old_p,
99             (ref $unregister_args eq 'ARRAY'
100             ? @$unregister_args
101             : ()
102             )
103             );
104              
105 0 0       0 if ($self->{PLUGS}{$new_a}) {
106 0         0 $@ = "Plugin named '$new_a' already exists ($self->{PLUGS}{$new_a}";
107 0         0 return;
108             }
109              
110 0 0       0 my $return = $self->_register(
111             $new_a,
112             $new_p,
113             (ref $register_args eq 'ARRAY'
114             ? @$register_args
115             : ()
116             )
117             );
118 0 0       0 return if !$return;
119              
120 0         0 for my $plugin (@{ $self->{PIPELINE} }) {
  0         0  
121 0 0       0 if ($plugin == $old_p) {
122 0         0 $plugin = $new_p;
123 0         0 last;
124             }
125             }
126              
127 0         0 return 1;
128             }
129              
130             sub remove {
131 1     1 1 3 my ($self, $old, @unregister_args) = @_;
132 1 50       5 my ($old_a, $old_p) = ref $old
133             ? ($self->{PLUGS}{$old}, $old)
134             : ($old, $self->{PLUGS}{$old})
135             ;
136              
137 1 50       4 if (!$old_p) {
138 0         0 $@ = "Plugin '$old_a' does not exist";
139 0         0 return;
140             }
141              
142 1         3 my $i = 0;
143 1         2 for my $plugin (@{ $self->{PIPELINE} }) {
  1         3  
144 1 50       5 if ($plugin == $old_p) {
145 1         2 splice(@{ $self->{PIPELINE} }, $i, 1);
  1         3  
146 1         2 last;
147             }
148 0         0 $i++;
149             }
150              
151 1         5 $self->_unregister($old_a, $old_p, @unregister_args);
152              
153 1 50       47 return wantarray ? ($old_p, $old_a) : $old_p;
154             }
155              
156             sub get {
157 4     4 1 6 my ($self, $old) = @_;
158            
159 4 50       19 my ($old_a, $old_p) = ref $old
160             ? ($self->{PLUGS}{$old}, $old)
161             : ($old, $self->{PLUGS}{$old})
162             ;
163              
164              
165 4 50       11 if (!$old_p) {
166 0         0 $@ = "Plugin '$old_a' does not exist";
167 0         0 return;
168             }
169              
170 4 50       18 return wantarray ? ($old_p, $old_a) : $old_p;
171             }
172              
173             sub get_index {
174 0     0 1 0 my ($self, $old) = @_;
175            
176 0 0       0 my ($old_a, $old_p) = ref $old
177             ? ($self->{PLUGS}{$old}, $old)
178             : ($old, $self->{PLUGS}{$old})
179             ;
180              
181 0 0       0 if (!$old_p) {
182 0         0 $@ = "Plugin '$old_a' does not exist";
183 0         0 return -1;
184             }
185              
186 0         0 my $i = 0;
187 0         0 for my $plugin (@{ $self->{PIPELINE} }) {
  0         0  
188 0 0       0 return $i if $plugin == $old_p;
189 0         0 $i++;
190             }
191              
192 0         0 return -1;
193             }
194              
195             sub insert_before {
196 0     0 1 0 my ($self, $old, $new_a, $new_p, @register_args) = @_;
197            
198 0 0       0 my ($old_a, $old_p) = ref $old
199             ? ($self->{PLUGS}{$old}, $old)
200             : ($old, $self->{PLUGS}{$old})
201             ;
202              
203 0 0       0 if (!$old_p) {
204 0         0 $@ = "Plugin '$old_a' does not exist";
205 0         0 return;
206             }
207              
208 0 0       0 if ($self->{PLUGS}{$new_a}) {
209 0         0 $@ = "Plugin named '$new_a' already exists ($self->{PLUGS}{$new_a}";
210 0         0 return;
211             }
212              
213 0         0 my $return = $self->_register($new_a, $new_p, @register_args);
214 0 0       0 return if !$return;
215              
216 0         0 my $i = 0;
217 0         0 for my $plugin (@{ $self->{PIPELINE} }) {
  0         0  
218 0 0       0 if ($plugin == $old_p) {
219 0         0 splice(@{ $self->{PIPELINE} }, $i, 0, $new_p);
  0         0  
220 0         0 last;
221             }
222 0         0 $i++;
223             }
224              
225 0         0 return 1;
226             }
227              
228             sub insert_after {
229 0     0 1 0 my ($self, $old, $new_a, $new_p, @register_args) = @_;
230 0 0       0 my ($old_a, $old_p) = ref $old
231             ? ($self->{PLUGS}{$old}, $old)
232             : ($old, $self->{PLUGS}{$old})
233             ;
234              
235 0 0       0 if (!$old_p) {
236 0         0 $@ = "Plugin '$old_a' does not exist";
237 0         0 return;
238             }
239              
240 0 0       0 if ($self->{PLUGS}{$new_a}) {
241 0         0 $@ = "Plugin named '$new_a' already exists ($self->{PLUGS}{$new_a}";
242 0         0 return;
243             }
244              
245 0         0 my $return = $self->_register($new_a, $new_p, @register_args);
246 0 0       0 return if !$return;
247              
248 0         0 my $i = 0;
249 0         0 for my $plugin (@{ $self->{PIPELINE} }) {
  0         0  
250 0 0       0 if ($plugin == $old_p) {
251 0         0 splice(@{ $self->{PIPELINE} }, $i+1, 0, $new_p);
  0         0  
252 0         0 last;
253             }
254 0         0 $i++;
255             }
256              
257 0         0 return 1;
258             }
259              
260             sub bump_up {
261 0     0 1 0 my ($self, $old, $diff) = @_;
262 0         0 my $idx = $self->get_index($old);
263              
264 0 0       0 return -1 if $idx < 0;
265              
266 0         0 my $pipeline = $self->{PIPELINE};
267 0   0     0 $diff ||= 1;
268              
269 0         0 my $pos = $idx - $diff;
270              
271 0 0       0 if ($pos < 0) {
272 0         0 carp "$idx - $diff is negative, moving to head of the pipeline";
273             }
274              
275 0         0 splice(@$pipeline, $pos, 0, splice(@$pipeline, $idx, 1));
276 0         0 return $pos;
277             }
278              
279             sub bump_down {
280 0     0 1 0 my ($self, $old, $diff) = @_;
281 0         0 my $idx = $self->get_index($old);
282              
283 0 0       0 return -1 if $idx < 0;
284              
285 0         0 my $pipeline = $self->{PIPELINE};
286 0   0     0 $diff ||= 1;
287              
288 0         0 my $pos = $idx + $diff;
289              
290 0 0       0 if ($pos >= @$pipeline) {
291 0         0 carp "$idx + $diff is too high, moving to back of the pipeline";
292             }
293              
294 0         0 splice(@$pipeline, $pos, 0, splice(@$pipeline, $idx, 1));
295 0         0 return $pos;
296             }
297              
298             sub _register {
299 1     1   3 my ($self, $alias, $plug, @register_args) = @_;
300 1 50       8 return if !defined $self->{OBJECT};
301              
302 1         2 my $return;
303 1         4 my $sub = "$self->{OBJECT}{_pluggable_reg_prefix}register";
304 1         2 local $@;
305 1         2 eval { $return = $plug->$sub($self->{OBJECT}, @register_args) };
  1         8  
306              
307 1 50       9 if ($@) {
    50          
308 0         0 chomp $@;
309 0         0 my $error = "$sub call on plugin '$alias' failed: $@";
310 0         0 $self->_handle_error($error, $plug, $alias);
311             }
312             elsif (!$return) {
313 0         0 my $error = "$sub call on plugin '$alias' did not return a true value";
314 0         0 $self->_handle_error($error, $plug, $alias);
315             }
316              
317 1         4 $self->{PLUGS}{$plug} = $alias;
318 1         3 $self->{PLUGS}{$alias} = $plug;
319            
320 1         9 $self->{OBJECT}->_pluggable_event(
321             "$self->{OBJECT}{_pluggable_prefix}plugin_add",
322             $alias, $plug,
323             );
324              
325 1         7 return $return;
326             }
327              
328             sub _unregister {
329 1     1   3 my ($self, $alias, $plug, @unregister_args) = @_;
330 1 50       6 return if !defined $self->{OBJECT};
331              
332 1         1 my $return;
333 1         4 my $sub = "$self->{OBJECT}{_pluggable_reg_prefix}unregister";
334 1         7 local $@;
335 1         2 eval { $return = $plug->$sub($self->{OBJECT}, @unregister_args) };
  1         5  
336              
337 1 50       423 if ($@) {
    50          
338 0         0 chomp $@;
339 0         0 my $error = "$sub call on plugin '$alias' failed: $@";
340 0         0 $self->_handle_error($error, $plug, $alias);
341             }
342             elsif (!$return) {
343 0         0 my $error = "$sub call on plugin '$alias' did not return a true value";
344 0         0 $self->_handle_error($error, $plug, $alias);
345             }
346              
347 1         3 delete $self->{PLUGS}{$plug};
348 1         3 delete $self->{PLUGS}{$alias};
349 1         4 delete $self->{HANDLES}{$plug};
350              
351 1         6 $self->{OBJECT}->_pluggable_event(
352             "$self->{OBJECT}{_pluggable_prefix}plugin_del",
353             $alias, $plug,
354             );
355              
356 1         6 return $return;
357             }
358              
359             sub _handle_error {
360 0     0     my ($self, $error, $plugin, $alias) = @_;
361              
362 0 0         warn "$error\n" if $self->{OBJECT}{_pluggable_debug};
363 0           $self->{OBJECT}->_pluggable_event(
364             "$self->{OBJECT}{_pluggable_prefix}plugin_error",
365             $error, $plugin, $alias,
366             );
367              
368 0           return;
369             }
370              
371             1;
372             __END__