File Coverage

blib/lib/RPC/ExtDirect.pm
Criterion Covered Total %
statement 82 89 92.1
branch 22 32 68.7
condition n/a
subroutine 17 19 89.4
pod 0 10 0.0
total 121 150 80.6


line stmt bran cond sub pod time code
1             package RPC::ExtDirect;
2              
3 22     22   16679 use strict;
  22         25  
  22         514  
4 22     22   61 use warnings;
  22         25  
  22         473  
5 22     22   103 no warnings 'uninitialized'; ## no critic
  22         21  
  22         546  
6              
7 22     22   70 use Carp;
  22         598  
  22         1143  
8 22     22   10902 use Attribute::Handlers;
  22         53042  
  22         88  
9              
10 22     22   9531 use RPC::ExtDirect::API;
  22         50  
  22         69  
11 22     22   85 use RPC::ExtDirect::Util;
  22         22  
  22         14706  
12              
13             ### PACKAGE VARIABLE ###
14             #
15             # Version of this module. This should be kept as a string
16             # because otherwise 'make dist' strips "insignificant" digits
17             # at the end.
18             #
19              
20             our $VERSION = '3.23';
21              
22             ### PACKAGE GLOBAL VARIABLE ###
23             #
24             # Debugging; defaults to off.
25             #
26             # DEPRECATED. Use `debug` Config option instead.
27             #
28              
29             our $DEBUG;
30              
31             # This is a bit hacky, but we've got to keep a reference to the API object
32             # so that *compilation time* attributes would work as expected,
33             # as well as the configuration options for the RPC::ExtDirect::API class.
34             {
35             my $api = RPC::ExtDirect::API->new();
36            
37             ### PUBLIC CLASS METHOD ###
38             #
39             # Return the global API instance
40             #
41            
42 538     538 0 7030 sub get_api { $api }
43             }
44              
45              
46             ### PUBLIC PACKAGE SUBROUTINE ###
47             #
48             # Provides a facility to assign package-level (action) properties.
49             # Despite its name, does not import anything to the caller package's
50             # namespace.
51             #
52              
53             sub import {
54 85     85   13684 my ($class, @args) = @_;
55              
56             # Nothing to do
57 85 100       4172 return unless @args;
58              
59             # Only hash-like arguments are supported
60 38 50       207 croak "Odd number of arguments in RPC::ExtDirect::import()"
61             unless (@args % 2) == 0;
62              
63 38         103 my %arg = @args;
64 38         87 %arg = map { lc $_ => delete $arg{ $_ } } keys %arg;
  57         197  
65              
66 38         130 my ($package, $filename, $line) = caller();
67            
68 38         86 my $api = $class->get_api;
69              
70             # Store Action (class) name as an alias for a package
71             my $action_name = defined $arg{action} ? $arg{action}
72             : defined $arg{class} ? $arg{class}
73             : undef
74 38 50       139 ;
    100          
75            
76             # We don't want to overwrite the existing Action, if any
77 38         130 $api->add_action(
78             package => $package,
79             action => $action_name,
80             no_overwrite => 1,
81             );
82              
83             # Store package level hooks
84 38         100 for my $type ( $api->HOOK_TYPES ) {
85 114         121 my $code = $arg{ $type };
86              
87 114 100       1209 $api->add_hook( package => $package, type => $type, code => $code )
88             if defined $code;
89             };
90             }
91              
92             ### PUBLIC ATTRIBUTE DEFINITION ###
93             #
94             # Define ExtDirect attribute subroutine and export it into UNIVERSAL
95             # namespace. Attribute processing phase depends on the perl version
96             # we're running under.
97             #
98              
99             {
100             my $phase = $] >= 5.012 ? 'BEGIN' : 'CHECK';
101             my $pkg = __PACKAGE__;
102            
103 22 50   22 0 98 eval <
  22 100   308   24  
  22         122  
  308         88140  
  308         352  
  308         784  
  308         1240  
  1         9  
104             sub UNIVERSAL::ExtDirect : ATTR(CODE,$phase) {
105             my \$attr = RPC::ExtDirect::Util::parse_attribute(\@_);
106            
107             eval { ${pkg}->add_method(\$attr) };
108              
109             if (\$@) { die 'ARRAY' eq ref(\$@) ? \$\@->[0] : \$@ }; };
110             END
111             }
112              
113             ### PUBLIC CLASS METHOD ###
114             #
115             # Add a hook to the global API
116             #
117             # DEPRECATED. See RPC::ExtDirect::API for replacement.
118             #
119              
120             sub add_hook {
121 0     0 0 0 my ($class, %arg) = @_;
122              
123 0         0 my $api = $class->get_api();
124            
125 0         0 $api->add_hook(%arg);
126              
127 0         0 return $arg{code};
128             }
129              
130             ### PUBLIC CLASS METHOD ###
131             #
132             # Return hook coderef by package and method, with hierarchical lookup.
133             #
134             # DEPRECATED. See RPC::ExtDirect::API for replacement.
135             #
136              
137             sub get_hook {
138 22     22 0 5554 my ($class, %arg) = @_;
139              
140 22         38 my $api = $class->get_api();
141 22         69 my $hook = $api->get_hook(%arg);
142            
143 22 50       381 return $hook ? $hook->code : undef;
144             }
145              
146             ### PUBLIC CLASS METHOD ###
147             #
148             # Adds Action name as an alias for a package
149             #
150             # DEPRECATED. See RPC::ExtDirect::API for replacement.
151             #
152              
153             sub add_action {
154 0     0 0 0 my ($class, $package, $action_for_pkg) = @_;
155            
156 0         0 my $api = $class->get_api();
157            
158 0         0 return $api->add_action(
159             package => $package,
160             action => $action_for_pkg,
161             );
162             }
163              
164             ### PUBLIC CLASS METHOD ###
165             #
166             # Returns the list of Actions that have ExtDirect methods
167             #
168             # DEPRECATED. See RPC::ExtDirect::API for replacement.
169             #
170              
171             sub get_action_list {
172 1     1 0 611 my ($class) = @_;
173            
174 1         4 my $api = $class->get_api();
175            
176 1         4 my @actions = sort $api->actions();
177            
178 1         5 return @actions;
179             }
180              
181             ### PUBLIC CLASS METHOD ###
182             #
183             # Returns the list of poll handler methods as list of
184             # arrayrefs: [ $action, $method ]
185             #
186             # DEPRECATED. See RPC::ExtDirect::API for replacement.
187             #
188              
189             sub get_poll_handlers {
190 1     1 0 381 my ($class) = @_;
191            
192 1         3 my $api = $class->get_api();
193 1         2 my @actions = $class->get_api->actions;
194 1         2 my @handlers;
195            
196 1         2 for my $name ( @actions ) {
197 4         9 my $action = $api->get_action_by_name($name);
198 4         11 my @methods = $action->polling_methods;
199            
200 4         13 push @handlers, [ $name, $_ ] for @methods;
201             }
202            
203 1         5 return @handlers;
204             }
205              
206             ### PUBLIC CLASS METHOD ###
207             #
208             # Adds a method to the global API
209             #
210             # DEPRECATED. See RPC::ExtDirect::API for replacement.
211             #
212              
213             sub add_method {
214 308     308 0 329 my ($class, $attribute_ref) = @_;
215            
216 308         473 my $api = $class->get_api;
217            
218 308         1069 return $api->add_method( %$attribute_ref );
219             }
220              
221             ### PUBLIC CLASS METHOD ###
222             #
223             # Returns the list of method names with ExtDirect attribute
224             # for $action_name, or all methods for all actions if $action_name
225             # is empty
226             #
227             # DEPRECATED. See RPC::ExtDirect::API for replacement.
228             #
229              
230             sub get_method_list {
231 5     5 0 1942 my ($class, $action_name) = @_;
232            
233 5         9 my $api = $class->get_api;
234            
235 5 100       13 my @actions = $action_name ? ( $action_name ) : $api->actions;
236 5         4 my @list;
237            
238 5         8 for my $name ( @actions ) {
239 8         16 my $action = $api->get_action_by_name($name);
240            
241             # The output of this method is inconsistent:
242             # when called with $action_name it returns the list of
243             # method names; when it is called with empty @_
244             # it returns the list of Action::method pairs.
245             # I don't remember what was the original intent here but
246             # we've got to keep up compatibility. The whole method is
247             # deprecated anyway...
248 8 100       12 my $tpl = $action_name ? "" : $name.'::';
249            
250 8         17 push @list, map { $tpl.$_ } $action->methods;
  30         41  
251             }
252            
253 5 50       29 return wantarray ? @list : shift @list;
254             }
255              
256             ### PUBLIC CLASS METHOD ###
257             #
258             # Returns parameters for given action and method name
259             # with ExtDirect attribute.
260             #
261             # Returns full attribute hash in list context.
262             # Croaks if called in scalar context.
263             #
264             # DEPRECATED. See RPC::ExtDirect::API for replacement.
265             #
266              
267             sub get_method_parameters {
268 15     15 0 5867 my ($class, $action_name, $method_name) = @_;
269            
270 15 50       31 croak "Wrong context" unless wantarray;
271            
272 15 50       21 croak "ExtDirect action name is required" unless defined $action_name;
273 15 50       28 croak "ExtDirect method name is required" unless defined $method_name;
274            
275 15         21 my $action = $class->get_api->get_action_by_name($action_name);
276            
277 15 50       28 croak "Can't find ExtDirect action $action"
278             unless $action;
279            
280 15         33 my $method = $action->method($method_name);
281              
282 15 50       25 croak "Can't find ExtDirect properties for method $method_name"
283             unless $method;
284            
285 15         33 return $method->get_api_definition_compat();
286             }
287              
288             1;