File Coverage

blib/lib/Lim/RPC/Protocols.pm
Criterion Covered Total %
statement 65 75 86.6
branch 16 34 47.0
condition 5 9 55.5
subroutine 12 12 100.0
pod 3 3 100.0
total 101 133 75.9


line stmt bran cond sub pod time code
1             package Lim::RPC::Protocols;
2              
3 7     7   11250 use common::sense;
  7         15  
  7         53  
4 7     7   350 use Carp;
  7         15  
  7         586  
5              
6 7     7   42 use Log::Log4perl ();
  7         17  
  7         159  
7 7     7   140 use Scalar::Util qw(blessed);
  7         16  
  7         368  
8 7     7   4933 use Module::Find qw(findsubmod);
  7         8607  
  7         426  
9              
10 7     7   52 use Lim ();
  7         13  
  7         26461  
11              
12             =encoding utf8
13              
14             =head1 NAME
15              
16             Lim::RPC::Protocols - Lim's RPC protocol loader and container
17              
18             =head1 VERSION
19              
20             See L for version.
21              
22             =cut
23              
24             our $VERSION = $Lim::VERSION;
25             our $INSTANCE;
26              
27             =head1 SYNOPSIS
28              
29             use Lim::RPC::Protocols;
30             $protocol = Lim::RPC::Protocols->instance->protocol('name');
31              
32             =head1 METHODS
33              
34             =over 4
35              
36             =cut
37              
38             sub _new {
39 2     2   26 my $this = shift;
40 2   33     33 my $class = ref($this) || $this;
41 2         14 my %args = ( @_ );
42 2         33 my $self = {
43             logger => Log::Log4perl->get_logger,
44             protocol => {},
45             protocol_name => {}
46             };
47 2         1077 bless $self, $class;
48              
49 2         34 $self->load;
50              
51 2 50       17 Lim::OBJ_DEBUG and $self->{logger}->debug('new ', __PACKAGE__, ' ', $self);
52 2         1514 $self;
53             }
54              
55             sub DESTROY {
56 2     2   7 my ($self) = @_;
57 2 50       11 Lim::OBJ_DEBUG and $self->{logger}->debug('destroy ', __PACKAGE__, ' ', $self);
58            
59 2         2425 delete $self->{protocol};
60             }
61              
62             END {
63 7     7   60 undef($INSTANCE);
64             }
65              
66             =item $instance = Lim::RPC::Protocols->instance
67              
68             Returns the singelton instance of this class.
69              
70             =cut
71              
72             sub instance {
73 2   33 2 1 86 $INSTANCE ||= Lim::RPC::Protocols->_new;
74             }
75              
76             =item $instance->load
77              
78             Loads all classes that exists on the system under Lim::RPC::Protocol::. Returns
79             the reference to itself even on error.
80              
81             =cut
82              
83             sub load {
84 2     2 1 6 my ($self) = @_;
85            
86 2         21 foreach my $module (findsubmod Lim::RPC::Protocol) {
87 12 50       21021 if (exists $self->{protocol}->{$module}) {
88 0 0       0 Lim::WARN and $self->{logger}->warn('Protocol ', $module, ' already loaded');
89 0         0 next;
90             }
91            
92 12 50       140 if ($module =~ /^([\w:]+)$/o) {
93 12         66 $module = $1;
94             }
95             else {
96 0         0 next;
97             }
98              
99 12         27 my $name;
100 12         25 eval {
101 12         1728 eval "require $module;";
102 12 100       205 die $@ if $@;
103 8         80 $name = $module->name;
104             };
105            
106 12 100       57 if ($@) {
107 4 50       67 Lim::WARN and $self->{logger}->warn('Unable to load protocol ', $module, ': ', $@);
108 4         4234 $self->{protocol}->{$module} = {
109             module => $module,
110             loaded => 0,
111             error => $@
112             };
113 4         15 next;
114             }
115            
116 8 50       111 unless ($name =~ /^[a-z0-9_\-\.]+$/o) {
117 0 0       0 Lim::WARN and $self->{logger}->warn('Unable to load protocol ', $module, ': Illegal characters in protocol name');
118 0         0 $self->{protocol}->{$module} = {
119             module => $module,
120             loaded => 0,
121             error => 'Illegal characters in protocol name'
122             };
123 0         0 next;
124             }
125              
126 8 50       53 if (exists $self->{protocol_name}->{$name}) {
127 0 0       0 Lim::WARN and $self->{logger}->warn('Protocol name ', $name, ' already loaded by module ', $self->{protocol_name}->{$name});
128 0         0 next;
129             }
130            
131 8         248 $self->{protocol}->{$module} = {
132             name => $name,
133             module => $module,
134             version => $module->VERSION,
135             loaded => 1
136             };
137 8         63 $self->{protocol_name}->{$name} = $module;
138             }
139              
140 2         10 $self;
141             }
142              
143             =item $protocol = $instance->protocol($name, ...)
144              
145             =cut
146              
147             sub protocol {
148 2     2 1 10 my $self = shift;
149 2         7 my $name = shift;
150              
151 2 50       11 if (defined $name) {
152 2         3 my $module;
153            
154 2         6 foreach (keys %{$self->{protocol}}) {
  2         14  
155 7 100 100     74 if ($self->{protocol}->{$_}->{loaded} and $self->{protocol}->{$_}->{name} eq $name) {
156 2         7 $module = $self->{protocol}->{$_}->{module};
157 2         7 last;
158             }
159             }
160            
161 2 50       10 if (defined $module) {
162 2         4 my $protocol;
163 2         5 eval {
164 2         30 $protocol = $module->new(@_);
165             };
166 2 50       13 if ($@) {
167 0 0       0 Lim::WARN and $self->{logger}->warn('Unable to create new instance of protocol ', $name, '(', $module, '): ', $@);
168             }
169             else {
170 2         18 return $protocol;
171             }
172             }
173             }
174 0           return;
175             }
176              
177             =back
178              
179             =head1 AUTHOR
180              
181             Jerry Lundström, C<< >>
182              
183             =head1 BUGS
184              
185             Please report any bugs or feature requests to L.
186              
187             =head1 SUPPORT
188              
189             You can find documentation for this module with the perldoc command.
190              
191             perldoc Lim::RPC::Protocols
192              
193             You can also look for information at:
194              
195             =over 4
196              
197             =item * Lim issue tracker (report bugs here)
198              
199             L
200              
201             =back
202              
203             =head1 ACKNOWLEDGEMENTS
204              
205             =head1 LICENSE AND COPYRIGHT
206              
207             Copyright 2012-2013 Jerry Lundström.
208              
209             This program is free software; you can redistribute it and/or modify it
210             under the terms of either: the GNU General Public License as published
211             by the Free Software Foundation; or the Artistic License.
212              
213             See http://dev.perl.org/licenses/ for more information.
214              
215              
216             =cut
217              
218             1; # End of Lim::RPC::Protocols