line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package OpenPlugin; |
2
|
|
|
|
|
|
|
|
3
|
7
|
|
|
7
|
|
303649
|
use strict; |
|
7
|
|
|
|
|
19
|
|
|
7
|
|
|
|
|
301
|
|
4
|
7
|
|
|
7
|
|
3727
|
use vars qw( $AUTOLOAD ); |
|
7
|
|
|
|
|
22
|
|
|
7
|
|
|
|
|
503
|
|
5
|
7
|
|
|
7
|
|
5867
|
use OpenPlugin::Plugin qw(); |
|
7
|
|
|
|
|
22
|
|
|
7
|
|
|
|
|
189
|
|
6
|
7
|
|
|
7
|
|
7543
|
use OpenPlugin::Utility qw(); |
|
7
|
|
|
|
|
19
|
|
|
7
|
|
|
|
|
172
|
|
7
|
7
|
|
|
7
|
|
45
|
use Log::Log4perl qw( get_logger ); |
|
7
|
|
|
|
|
21
|
|
|
7
|
|
|
|
|
48
|
|
8
|
|
|
|
|
|
|
|
9
|
7
|
|
|
7
|
|
574
|
use constant STATE => '_state'; |
|
7
|
|
|
|
|
14
|
|
|
7
|
|
|
|
|
373
|
|
10
|
7
|
|
|
7
|
|
35
|
use constant TOGGLE => '_toggle'; |
|
7
|
|
|
|
|
12
|
|
|
7
|
|
|
|
|
476
|
|
11
|
7
|
|
|
7
|
|
35
|
use constant PLUGIN => '_plugin'; |
|
7
|
|
|
|
|
12
|
|
|
7
|
|
|
|
|
306
|
|
12
|
7
|
|
|
7
|
|
37
|
use constant PLUGINCONF => '_pluginconf'; |
|
7
|
|
|
|
|
12
|
|
|
7
|
|
|
|
|
328
|
|
13
|
7
|
|
|
7
|
|
35
|
use constant INSTANCE => '_instance'; |
|
7
|
|
|
|
|
14
|
|
|
7
|
|
|
|
|
17639
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
$OpenPlugin::VERSION = '0.11'; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# We'll need the logger var throughout this entire file |
18
|
|
|
|
|
|
|
my $logger; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
sub new { |
21
|
6
|
|
|
6
|
1
|
624
|
my $pkg = shift; |
22
|
6
|
|
|
|
|
25
|
my $params = { @_ }; |
23
|
6
|
|
33
|
|
|
51
|
my $class = ref $pkg || $pkg; |
24
|
6
|
|
|
|
|
21
|
my $self = bless( {}, $class ); |
25
|
|
|
|
|
|
|
|
26
|
6
|
|
|
|
|
43
|
$self->init( $params->{'init'} ); |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# Save all the parameters which were passed in |
29
|
6
|
|
|
|
|
2496
|
$self->state("command_line", $params ); |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# TODO: We should try and get all this config stuff into the Config plugin |
32
|
|
|
|
|
|
|
# if at all possible, I don't think it belongs here |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# Read configuration from file if given. Otherwise, see if the package var |
35
|
|
|
|
|
|
|
# has our config in it |
36
|
6
|
|
66
|
|
|
53
|
$params->{'config'}{'src'} ||= $OpenPlugin::Config::Src; |
37
|
|
|
|
|
|
|
|
38
|
6
|
50
|
66
|
|
|
97
|
if ( $params->{'config'}{'src'} or $params->{'config'}{'data'} ) { |
39
|
|
|
|
|
|
|
|
40
|
6
|
|
|
|
|
36
|
$self->load_config( $params ); |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
# Quit if we haven't been given some sort of config to use |
44
|
|
|
|
|
|
|
else { |
45
|
0
|
|
|
|
|
0
|
die "No configuration given! You need to pass in the location ", |
46
|
|
|
|
|
|
|
"to your configuration file, or pass in a hashref containing ", |
47
|
|
|
|
|
|
|
"your configuration data."; |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
6
|
|
|
|
|
53
|
$self->register_plugins; |
51
|
|
|
|
|
|
|
|
52
|
4
|
|
|
|
|
27
|
return $self; |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
# Set up some stuff before we begin loading any plugins |
56
|
|
|
|
|
|
|
sub init { |
57
|
6
|
|
|
6
|
0
|
24
|
my ( $self, $params ) = @_; |
58
|
|
|
|
|
|
|
|
59
|
6
|
|
50
|
|
|
52
|
my $log_conf = $params->{'log'} || q( |
60
|
|
|
|
|
|
|
log4perl.rootLogger = WARN, stderr |
61
|
|
|
|
|
|
|
log4perl.appender.stderr = Log::Dispatch::Screen |
62
|
|
|
|
|
|
|
log4perl.appender.stderr.layout = org.apache.log4j.PatternLayout |
63
|
|
|
|
|
|
|
log4perl.appender.stderr.layout.ConversionPattern = %C (%L) %m%n |
64
|
|
|
|
|
|
|
); |
65
|
|
|
|
|
|
|
|
66
|
6
|
|
|
|
|
47
|
Log::Log4perl::init( \$log_conf ); |
67
|
6
|
|
|
|
|
201148
|
$logger = get_logger("OpenPlugin"); |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
######################################## |
72
|
|
|
|
|
|
|
# Public methods |
73
|
|
|
|
|
|
|
######################################## |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# This gets and sets state information for user requests. For instance, we can |
76
|
|
|
|
|
|
|
# maintain the current user and group, whether the user is an administrator, |
77
|
|
|
|
|
|
|
# etc. |
78
|
|
|
|
|
|
|
sub state { |
79
|
152
|
|
|
152
|
1
|
309
|
my ( $self, $key, $value ) = @_; |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# Just a key passed in, return a single value |
83
|
152
|
50
|
66
|
|
|
2231
|
if( defined $key and not defined $value ) { |
|
|
100
|
66
|
|
|
|
|
84
|
0
|
|
|
|
|
0
|
$logger->info("Calling state() with key [$key]."); |
85
|
|
|
|
|
|
|
|
86
|
0
|
|
|
|
|
0
|
return $self->{ STATE() }{ $key }; |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
# We have a key and value, so assign the value to the key |
90
|
|
|
|
|
|
|
elsif( defined $key and defined $value ) { |
91
|
36
|
|
|
|
|
326
|
$logger->info("Calling state() with key [$key] and value [$value]."); |
92
|
|
|
|
|
|
|
|
93
|
36
|
|
|
|
|
423
|
return $self->{ STATE() }{ $key } = $value; |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
# No key or value, return the entire state hash |
97
|
|
|
|
|
|
|
else { |
98
|
116
|
|
|
|
|
405
|
$logger->info("Calling state() with no parameters."); |
99
|
|
|
|
|
|
|
|
100
|
116
|
|
|
|
|
2048
|
return $self->{ STATE() }; |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# Cleans up the current state in this object and sends a message to |
106
|
|
|
|
|
|
|
# all plugins to cleanup their state as well. |
107
|
|
|
|
|
|
|
sub cleanup { |
108
|
0
|
|
|
0
|
1
|
0
|
my ( $self ) = @_; |
109
|
|
|
|
|
|
|
|
110
|
0
|
|
|
|
|
0
|
$logger->info( "Running cleanup()" ); |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
# Allow plugins to clean up their own state |
113
|
0
|
|
|
|
|
0
|
foreach my $plugin ( $self->loaded_plugins ) { |
114
|
0
|
|
|
|
|
0
|
$self->$plugin()->cleanup; |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# Completely erase all state related information |
118
|
0
|
|
|
|
|
0
|
$self->{ STATE() } = {}; |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
# FIXME: This might not be necessary anymore |
121
|
|
|
|
|
|
|
# Recreate a hash key for each plugin |
122
|
0
|
|
|
|
|
0
|
foreach my $plugin ( $self->loaded_plugins ) { |
123
|
0
|
|
|
|
|
0
|
$self->state( $plugin, {} ); |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
# This should be called before the object is taken out of scope and |
129
|
|
|
|
|
|
|
# should probably incorporated into a DESTROY() method. |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub shutdown { |
132
|
0
|
|
|
0
|
0
|
0
|
my ( $self ) = @_; |
133
|
0
|
|
|
|
|
0
|
$logger->info( "Calling shutdown() from OP" ); |
134
|
0
|
|
|
|
|
0
|
$self->cleanup(); |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
# ... do any additional cleanup so we don't have dangling/circular |
137
|
|
|
|
|
|
|
# references, etc.... |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
######################################## |
143
|
|
|
|
|
|
|
# Accessor methods |
144
|
|
|
|
|
|
|
######################################## |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
# Get a list of all plugins which the config plugin knows about |
147
|
|
|
|
|
|
|
sub get_plugins { |
148
|
31
|
|
|
31
|
0
|
74
|
my ( $self, $plugin ) = @_; |
149
|
|
|
|
|
|
|
|
150
|
31
|
100
|
|
|
|
94
|
if( $plugin ) { |
151
|
25
|
|
|
|
|
41
|
return sort keys %{ $self->config->{'plugin'}{ $plugin }{'plugin'} }; |
|
25
|
|
|
|
|
96
|
|
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
else { |
154
|
6
|
|
|
|
|
12
|
return sort keys %{ $self->config->{'plugin'} }; |
|
6
|
|
|
|
|
22
|
|
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# Get a list of all drivers for a given plugin |
159
|
|
|
|
|
|
|
sub get_drivers { |
160
|
27
|
|
|
27
|
0
|
48
|
my ( $self, $plugin ) = @_; |
161
|
|
|
|
|
|
|
|
162
|
27
|
|
|
|
|
908
|
return sort keys %{ $self->{ PLUGINCONF() }{ $plugin }{'driver'} } |
|
27
|
|
|
|
|
163
|
|
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
# Save any info that we have relating to a plugins configuration |
166
|
|
|
|
|
|
|
sub set_plugin_info { |
167
|
27
|
|
|
27
|
0
|
67
|
my ( $self, $plugin, $nested_plugin ) = @_; |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
# $plugin_info contains all the information about a given plugin that was |
170
|
|
|
|
|
|
|
# found in the configuration file |
171
|
27
|
|
|
|
|
42
|
my $plugin_info; |
172
|
27
|
100
|
|
|
|
79
|
if( $nested_plugin ) { |
173
|
8
|
|
|
|
|
24
|
$plugin_info = |
174
|
|
|
|
|
|
|
$self->config->{'plugin'}{ $plugin }{'plugin'}{ $nested_plugin }; |
175
|
8
|
|
|
|
|
18
|
$plugin = $nested_plugin; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
else { |
178
|
19
|
|
|
|
|
70
|
$plugin_info = $self->config->{'plugin'}{ $plugin }; |
179
|
|
|
|
|
|
|
} |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
# We definitely cannot load a plugin without a driver. Warn and skip if |
182
|
|
|
|
|
|
|
# that is the case. |
183
|
27
|
50
|
33
|
|
|
240
|
unless ( ref $plugin_info eq 'HASH' and $plugin_info->{'driver'} ) { |
184
|
0
|
|
|
|
|
0
|
$logger->warn("Invalid driver listed for [$plugin]: ", |
185
|
|
|
|
|
|
|
"[$plugin_info->{driver}]. Skipping." ); |
186
|
|
|
|
|
|
|
|
187
|
0
|
|
|
|
|
0
|
return undef; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
27
|
|
|
|
|
192
|
$logger->info( "Driver type found for [$plugin]: ", |
191
|
|
|
|
|
|
|
"[$plugin_info->{driver}]" ); |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
# Store this configuration for whenever we need it |
194
|
27
|
|
|
|
|
244
|
return $self->{ PLUGINCONF() }{ $plugin } = $plugin_info; |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
# Retrieve config information listed about a given plugin |
199
|
|
|
|
|
|
|
sub get_plugin_info { |
200
|
58
|
|
|
58
|
0
|
405
|
my ( $self, $plugin ) = @_; |
201
|
|
|
|
|
|
|
|
202
|
58
|
|
|
|
|
410
|
return $self->{ PLUGINCONF() }{ $plugin }; |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
# Get the name of the class name to use for a given driver |
206
|
|
|
|
|
|
|
sub get_plugin_class { |
207
|
28
|
|
|
28
|
0
|
272
|
my ( $self, $plugin, $driver ) = @_; |
208
|
|
|
|
|
|
|
|
209
|
28
|
50
|
|
|
|
73
|
return undef unless $driver; |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
# Get the class name for the driver, as defined in the drivermap file |
212
|
28
|
|
|
|
|
70
|
my $plugin_class = $self->config->{'drivermap'}{ $plugin }{ $driver }; |
213
|
|
|
|
|
|
|
|
214
|
28
|
|
|
|
|
148
|
$logger->info( "Plugin class found for [$plugin]: [$plugin_class]" ); |
215
|
|
|
|
|
|
|
|
216
|
28
|
|
|
|
|
227
|
return $plugin_class; |
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
# Retrieve a list of plugins which are currently loaded, return the value we |
221
|
|
|
|
|
|
|
# received when we called it's load() function earlier |
222
|
|
|
|
|
|
|
sub loaded_plugins { |
223
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
# Return an empty list if no plugins are loaded |
226
|
0
|
0
|
|
|
|
0
|
unless ( ref $self->{ PLUGIN() } eq 'HASH' ) { |
227
|
0
|
|
|
|
|
0
|
return (); |
228
|
|
|
|
|
|
|
} |
229
|
|
|
|
|
|
|
|
230
|
0
|
|
|
|
|
0
|
return sort keys %{ $self->{ PLUGIN() } }; |
|
0
|
|
|
|
|
0
|
|
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
# Save the plugin instance (object) that we received by calling its new() |
234
|
|
|
|
|
|
|
# function |
235
|
|
|
|
|
|
|
sub set_plugin_instance { |
236
|
30
|
|
|
30
|
0
|
121
|
my ( $self, $plugin, $driver, $instance ) = @_; |
237
|
|
|
|
|
|
|
|
238
|
30
|
|
|
|
|
195
|
return $self->{ INSTANCE() }{ $plugin }{ $driver } = $instance; |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
# Set which driver will be used when one isn't explicitely given |
242
|
|
|
|
|
|
|
sub set_default_driver { |
243
|
33
|
|
|
33
|
0
|
74
|
my ( $self, $plugin, $driver ) = @_; |
244
|
|
|
|
|
|
|
|
245
|
33
|
|
|
|
|
192
|
return $self->{ PLUGINCONF() }{ $plugin }{'default'} = $driver; |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
# Get the name of the default driver for a given plugin |
249
|
|
|
|
|
|
|
sub get_default_driver { |
250
|
155
|
|
|
155
|
0
|
218
|
my ( $self, $plugin ) = @_; |
251
|
|
|
|
|
|
|
|
252
|
155
|
|
|
|
|
1117
|
return $self->{ PLUGINCONF() }{ $plugin }{'default'}; |
253
|
|
|
|
|
|
|
} |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
######################################## |
257
|
|
|
|
|
|
|
# Plugin Instanciation |
258
|
|
|
|
|
|
|
######################################## |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
# TODO: I'd like all these functions to be able to handle plugins defined in |
261
|
|
|
|
|
|
|
# the config file to be nested at an arbitrary depth. They currently can only |
262
|
|
|
|
|
|
|
# be two levels deep. |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
# Get a list of plugins, and register them |
265
|
|
|
|
|
|
|
sub register_plugins { |
266
|
6
|
|
|
6
|
0
|
16
|
my $self = shift; |
267
|
|
|
|
|
|
|
|
268
|
6
|
|
|
|
|
145
|
foreach my $plugin ( $self->get_plugins ) { |
269
|
19
|
|
|
|
|
85
|
$self->set_plugin_info( $plugin ); |
270
|
|
|
|
|
|
|
|
271
|
19
|
|
|
|
|
70
|
$self->register_plugin( $plugin ); |
272
|
|
|
|
|
|
|
} |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
} |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
# Decide how and when to load a plugin |
277
|
|
|
|
|
|
|
sub register_plugin { |
278
|
27
|
|
|
27
|
0
|
338
|
my ( $self, $plugin ) = @_; |
279
|
|
|
|
|
|
|
|
280
|
27
|
|
|
|
|
87
|
my @drivers = $self->get_drivers( $plugin ); |
281
|
27
|
|
|
|
|
58
|
my $driver_count = scalar @drivers; |
282
|
27
|
|
|
|
|
73
|
my $default_driver = $self->get_default_driver( $plugin ); |
283
|
|
|
|
|
|
|
|
284
|
27
|
|
|
|
|
78
|
foreach my $driver ( @drivers ) { |
285
|
|
|
|
|
|
|
|
286
|
27
|
50
|
33
|
|
|
358
|
if( $driver_count == 1 and not defined $default_driver ) { |
287
|
27
|
|
|
|
|
80
|
$self->set_default_driver( $plugin, $driver ); |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
|
290
|
27
|
|
|
|
|
70
|
my $class_identifier = $plugin . "-" . $driver; |
291
|
27
|
|
|
|
|
113
|
my $class = $self->get_plugin_class( $plugin, $driver ); |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
# These plugins have a "load" time of "Startup", meaning they are |
294
|
|
|
|
|
|
|
# loaded when the main OpenPlugin module is |
295
|
27
|
100
|
|
|
|
76
|
if( $self->get_plugin_info( $plugin )->{'load'} eq "Startup" ) { |
|
|
50
|
|
|
|
|
|
296
|
|
|
|
|
|
|
|
297
|
26
|
50
|
|
|
|
1596
|
unless( grep m/^$class$/, |
298
|
|
|
|
|
|
|
OpenPlugin::Plugin->get_loaded_classes ) { |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
# Tell OpenPlugin::Plugin that we have a new class that we |
301
|
|
|
|
|
|
|
# wish to load now |
302
|
26
|
|
|
|
|
1575
|
OpenPlugin::Plugin->add_factory_type( |
303
|
|
|
|
|
|
|
$class_identifier => $class ); |
304
|
|
|
|
|
|
|
} |
305
|
|
|
|
|
|
|
|
306
|
24
|
|
|
|
|
868
|
$self->init_plugin( $plugin, $driver ); |
307
|
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
# These plugins have a "load" time of "Auto", meaning they are |
310
|
|
|
|
|
|
|
# loaded on demand. If they aren't ever used, they'll never be |
311
|
|
|
|
|
|
|
# loaded |
312
|
|
|
|
|
|
|
elsif ( $self->get_plugin_info( $plugin )->{'load'} eq "Auto" ) { |
313
|
|
|
|
|
|
|
|
314
|
1
|
50
|
|
|
|
20
|
unless( grep m/^$class$/, |
315
|
|
|
|
|
|
|
OpenPlugin::Plugin->get_registered_classes ) { |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
# Tell OpenPlugin::Plugin about a class, so it can load it |
318
|
|
|
|
|
|
|
# if and when we finally decide to use it |
319
|
1
|
|
|
|
|
15
|
OpenPlugin::Plugin->register_factory_type( |
320
|
|
|
|
|
|
|
$class_identifier => $self->get_plugin_class( $plugin, |
321
|
|
|
|
|
|
|
$driver )); |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
} |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
# We need to know how to load a plugin, it doesn't seem appropriate |
327
|
|
|
|
|
|
|
# to guess. If the configuration isn't correct, give a warning |
328
|
|
|
|
|
|
|
# message, but skip loading it. |
329
|
|
|
|
|
|
|
else { |
330
|
0
|
|
|
|
|
0
|
$logger->warn("Invalid load time listed for [$plugin]: [", |
331
|
|
|
|
|
|
|
$self->{ PLUGINCONF() }{ $plugin }{'load'}, |
332
|
|
|
|
|
|
|
"]. Skipping." ); |
333
|
|
|
|
|
|
|
} |
334
|
|
|
|
|
|
|
} |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
# Handle plugins defined within other plugins |
337
|
25
|
|
|
|
|
161
|
foreach my $nested_plugin ( $self->get_plugins( $plugin )) { |
338
|
8
|
|
|
|
|
31
|
$self->set_plugin_info( $plugin, $nested_plugin ); |
339
|
|
|
|
|
|
|
|
340
|
8
|
|
|
|
|
49
|
$self->register_plugin( $nested_plugin ); |
341
|
|
|
|
|
|
|
} |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
# Make a plugin available to programs using us |
346
|
|
|
|
|
|
|
sub init_plugin { |
347
|
24
|
|
|
24
|
0
|
66
|
my ( $self, $plugin, $driver ) = @_; |
348
|
|
|
|
|
|
|
|
349
|
24
|
50
|
|
|
|
122
|
unless( $plugin ) { |
350
|
0
|
|
|
|
|
0
|
$self->exception->throw( "You must call init_plugin() with a ", |
351
|
|
|
|
|
|
|
"plugin name!" ); |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
|
354
|
24
|
50
|
|
|
|
99
|
unless( $self->get_plugin_info( $plugin )) { |
355
|
0
|
|
|
|
|
0
|
$self->exception->throw( "You attemped to call [$plugin], which is ", |
356
|
|
|
|
|
|
|
"not a valid plugin!" ); |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
# No driver name is okay, we'll just use the default |
360
|
24
|
|
33
|
|
|
87
|
$driver ||= $self->get_default_driver( $plugin ); |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
# Create and save an instance for this driver |
363
|
24
|
|
|
|
|
101
|
my $instance = $self->create_plugin_instance( $plugin, $driver ); |
364
|
24
|
|
|
|
|
173
|
$self->set_plugin_instance( $plugin, $driver, $instance ); |
365
|
|
|
|
|
|
|
|
366
|
24
|
|
|
|
|
99
|
$self->generate_plugin_method_call( $plugin ); |
367
|
|
|
|
|
|
|
|
368
|
24
|
|
|
|
|
107
|
$self->{ PLUGIN() }{ $plugin } = $self->$plugin( $driver )->load(); |
369
|
|
|
|
|
|
|
} |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
# Create a new instance of a plugin |
372
|
|
|
|
|
|
|
sub create_plugin_instance { |
373
|
24
|
|
|
24
|
0
|
57
|
my ( $self, $plugin, $driver ) = @_; |
374
|
|
|
|
|
|
|
|
375
|
24
|
|
|
|
|
68
|
my $class_identifier = $plugin . "-" . $driver; |
376
|
|
|
|
|
|
|
|
377
|
24
|
|
|
|
|
120
|
return OpenPlugin::Plugin->new( $class_identifier, $self, |
378
|
|
|
|
|
|
|
$self->state->{'command_line'}{ $plugin }); |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
# Build a method call for a given plugin |
382
|
|
|
|
|
|
|
sub generate_plugin_method_call { |
383
|
30
|
|
|
30
|
0
|
73
|
my ( $self, $plugin ) = @_; |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
# Create the new method in the current package's namespace |
386
|
30
|
|
|
|
|
91
|
my $method = __PACKAGE__ . '::' . $plugin; |
387
|
7
|
|
|
7
|
|
62
|
no strict 'refs'; |
|
7
|
|
|
|
|
22
|
|
|
7
|
|
|
|
|
5115
|
|
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
# Don't redefine existing method names. This will both save us time, and |
390
|
|
|
|
|
|
|
# is more secure. |
391
|
30
|
50
|
|
|
|
58
|
unless ( defined &{ $method } ) { |
|
30
|
|
|
|
|
293
|
|
392
|
|
|
|
|
|
|
|
393
|
30
|
|
|
|
|
181
|
$logger->info("Generating method [$method]"); |
394
|
|
|
|
|
|
|
|
395
|
30
|
|
|
|
|
1465
|
*{ $method } = |
396
|
|
|
|
|
|
|
sub { |
397
|
152
|
|
|
152
|
|
12634
|
my ( $self, $driver ) = @_; |
398
|
152
|
|
66
|
|
|
663
|
$driver ||= $self->get_default_driver( $plugin ); |
399
|
|
|
|
|
|
|
|
400
|
152
|
50
|
|
|
|
899
|
unless( $driver ) { |
401
|
0
|
|
|
|
|
0
|
$self->exception->throw( "No driver found for [$plugin].", |
402
|
|
|
|
|
|
|
"If you have multiple drivers ", |
403
|
|
|
|
|
|
|
"defined, you must assign one ", |
404
|
|
|
|
|
|
|
"as the default." ); |
405
|
|
|
|
|
|
|
} |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
# If there is already an instance for this particular driver, |
408
|
|
|
|
|
|
|
# return it |
409
|
152
|
50
|
|
|
|
576
|
if( $self->{ INSTANCE() }{ $plugin }{ $driver } ) { |
410
|
152
|
|
|
|
|
1291
|
return $self->{ INSTANCE() }{ $plugin }{ $driver }; |
411
|
|
|
|
|
|
|
} |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
# If there isn't yet an instance (typical when the plugin isn't |
414
|
|
|
|
|
|
|
# loaded at startup), create one and return it |
415
|
|
|
|
|
|
|
else { |
416
|
0
|
|
|
|
|
0
|
my $instance = $self->create_plugin_instance( $plugin, |
417
|
|
|
|
|
|
|
$driver ); |
418
|
|
|
|
|
|
|
|
419
|
0
|
|
|
|
|
0
|
return $self->set_plugin_instance( $plugin, $driver, |
420
|
|
|
|
|
|
|
$instance ); |
421
|
|
|
|
|
|
|
} |
422
|
|
|
|
|
|
|
} |
423
|
30
|
|
|
|
|
1733
|
} |
424
|
|
|
|
|
|
|
} |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
######################################## |
428
|
|
|
|
|
|
|
# AUTOLOAD |
429
|
|
|
|
|
|
|
# (so great it gets its own section!) |
430
|
|
|
|
|
|
|
######################################## |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
sub AUTOLOAD { |
433
|
0
|
|
|
0
|
|
0
|
my ( $self, $driver ) = @_; |
434
|
0
|
|
|
|
|
0
|
my $request = $AUTOLOAD; |
435
|
|
|
|
|
|
|
|
436
|
0
|
|
|
|
|
0
|
$request =~ s/.*://; |
437
|
|
|
|
|
|
|
|
438
|
0
|
|
|
|
|
0
|
$logger->info( "Autoload request: [$request]\n" ); |
439
|
0
|
|
|
|
|
0
|
$self->init_plugin( $request, $driver ); |
440
|
0
|
|
|
|
|
0
|
$self->$request( $driver ); |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
# Lets not go looking for DESTROY via AUTOLOAD |
445
|
0
|
|
|
0
|
|
0
|
sub DESTROY { } |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
######################################## |
449
|
|
|
|
|
|
|
# CONFIGURATION |
450
|
|
|
|
|
|
|
######################################## |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
# Configuration is different from other plugins because of the bootstrapping |
453
|
|
|
|
|
|
|
# issue. |
454
|
|
|
|
|
|
|
sub load_config { |
455
|
6
|
|
|
6
|
0
|
15
|
my ( $self, $params ) = @_; |
456
|
|
|
|
|
|
|
|
457
|
6
|
50
|
|
|
|
98
|
unless( grep m/^OpenPlugin::Config$/, |
458
|
|
|
|
|
|
|
OpenPlugin::Plugin->get_loaded_classes ) { |
459
|
|
|
|
|
|
|
|
460
|
6
|
|
|
|
|
110
|
OpenPlugin::Plugin->add_factory_type( |
461
|
|
|
|
|
|
|
"config" => 'OpenPlugin::Config' ); |
462
|
|
|
|
|
|
|
} |
463
|
|
|
|
|
|
|
|
464
|
6
|
|
|
|
|
142
|
my $config = OpenPlugin::Plugin->new( 'config', $self, |
465
|
|
|
|
|
|
|
$params->{'config'} ); |
466
|
|
|
|
|
|
|
|
467
|
6
|
100
|
|
|
|
63
|
if( $params->{'config'}{'src'} ) { |
|
|
50
|
|
|
|
|
|
468
|
1
|
|
|
|
|
20
|
$self->set_plugin_instance( "config", 'built-in', $config->read ); |
469
|
|
|
|
|
|
|
} |
470
|
|
|
|
|
|
|
elsif( $params->{'config'}{'data'} ) { |
471
|
5
|
|
|
|
|
28
|
$self->set_plugin_instance( "config", 'built-in', |
472
|
|
|
|
|
|
|
$config->read( $params->{'config'}{'data'} )); |
473
|
|
|
|
|
|
|
} |
474
|
|
|
|
|
|
|
|
475
|
6
|
|
|
|
|
67
|
$self->generate_plugin_method_call( "config" ); |
476
|
6
|
|
|
|
|
33
|
$self->set_default_driver( "config", "built-in" ); |
477
|
|
|
|
|
|
|
|
478
|
6
|
50
|
66
|
|
|
102
|
if( $params->{'config'}{'data'} and $params->{'config'}{'src'} ) { |
479
|
0
|
|
|
|
|
|
$self->config->read( $params->{'config'}{'data'} ); |
480
|
|
|
|
|
|
|
} |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
} |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
1; |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
__END__ |