| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package OpenInteract::Startup; |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# $Id: Startup.pm,v 1.37 2003/03/13 03:26:34 lachoy Exp $ |
|
4
|
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
877
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
46
|
|
|
6
|
1
|
|
|
1
|
|
5
|
use Cwd qw( cwd ); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
83
|
|
|
7
|
1
|
|
|
1
|
|
1093
|
use Data::Dumper qw( Dumper ); |
|
|
1
|
|
|
|
|
7078
|
|
|
|
1
|
|
|
|
|
87
|
|
|
8
|
1
|
|
|
1
|
|
11
|
use File::Basename qw( dirname ); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
73
|
|
|
9
|
1
|
|
|
1
|
|
6
|
use File::Path qw(); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
18
|
|
|
10
|
1
|
|
|
1
|
|
1304
|
use Getopt::Long qw( GetOptions ); |
|
|
1
|
|
|
|
|
13756
|
|
|
|
1
|
|
|
|
|
9
|
|
|
11
|
1
|
|
|
1
|
|
762
|
use OpenInteract::Config; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
44
|
|
|
12
|
1
|
|
|
1
|
|
515
|
use OpenInteract::Config::GlobalOverride; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
35
|
|
|
13
|
1
|
|
|
1
|
|
8
|
use OpenInteract::Error; |
|
|
1
|
|
|
|
|
21
|
|
|
|
1
|
|
|
|
|
21
|
|
|
14
|
1
|
|
|
1
|
|
884
|
use OpenInteract::Package; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
use OpenInteract::PackageRepository; |
|
16
|
|
|
|
|
|
|
use SPOPS::ClassFactory; |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
$OpenInteract::Startup::VERSION = sprintf("%d.%02d", q$Revision: 1.37 $ =~ /(\d+)\.(\d+)/); |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
use constant DEBUG => 0; |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
my $TEMP_LIB_DIR = 'tmplib'; |
|
23
|
|
|
|
|
|
|
my $REPOS_CLASS = 'OpenInteract::PackageRepository'; |
|
24
|
|
|
|
|
|
|
my $PKG_CLASS = 'OpenInteract::Package'; |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub main_initialize { |
|
27
|
|
|
|
|
|
|
my ( $class, $p ) = @_; |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# Ensure we can find the base configuration, and use it or read it in |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
return undef unless ( $p->{base_config} or $p->{base_config_file} ); |
|
32
|
|
|
|
|
|
|
my $bc = $p->{base_config} || |
|
33
|
|
|
|
|
|
|
$class->read_base_config({ filename => $p->{base_config_file} }); |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# Create our main config object |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
my $C = $class->create_config({ base_config => $bc }); |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
# Initialize the package repository class -- it's a SPOPS class, |
|
40
|
|
|
|
|
|
|
# but a really simple one |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
$REPOS_CLASS->class_initialize( $C ); |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
# Read in our fundamental modules -- these should be in our @INC |
|
45
|
|
|
|
|
|
|
# already, since the 'request_class' is in |
|
46
|
|
|
|
|
|
|
# 'OpenInteract/OpenInteract' and the 'stash_class' is in |
|
47
|
|
|
|
|
|
|
# 'MyApp/MyApp' |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
$class->require_module({ class => [ $bc->{request_class}, $bc->{stash_class} ] }); |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
# Either use a package list provided or read in all the packages from |
|
52
|
|
|
|
|
|
|
# the website package database |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
my $packages = []; |
|
55
|
|
|
|
|
|
|
my $repository = $REPOS_CLASS->fetch( undef, { directory => $bc->{website_dir} } ); |
|
56
|
|
|
|
|
|
|
if ( my $package_list = $p->{package_list} ) { |
|
57
|
|
|
|
|
|
|
foreach my $pkg_name ( @{ $p->{package_list} } ) { |
|
58
|
|
|
|
|
|
|
my $pkg_info = $repository->fetch_pacakge_by_name({ name => $pkg_name }); |
|
59
|
|
|
|
|
|
|
push @{ $packages }, $pkg_info if ( $pkg_info ); |
|
60
|
|
|
|
|
|
|
} |
|
61
|
|
|
|
|
|
|
} |
|
62
|
|
|
|
|
|
|
else { |
|
63
|
|
|
|
|
|
|
$packages = $repository->fetch_all_packages(); |
|
64
|
|
|
|
|
|
|
} |
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# We keep track of the package names currently installed and use them |
|
67
|
|
|
|
|
|
|
# elsewhere in the system |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
$C->{package_list} = [ map { $_->{name} } @{ $packages } ]; |
|
70
|
|
|
|
|
|
|
foreach my $pkg_info ( @{ $packages } ) { |
|
71
|
|
|
|
|
|
|
$class->process_package( $pkg_info, $C ); |
|
72
|
|
|
|
|
|
|
} |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
$class->_process_global_overrides( $C ); |
|
75
|
|
|
|
|
|
|
$class->_require_extra_classes( $C ); |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
# Store the configuration for later use |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
my $stash_class = $bc->{stash_class}; |
|
80
|
|
|
|
|
|
|
$stash_class->set_stash( 'config', $C ); |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# Create an instance of $R since later steps might need it -- |
|
83
|
|
|
|
|
|
|
# particularly SPOPS initialization which may want a connection to |
|
84
|
|
|
|
|
|
|
# the datasource during setup. (Crossing fingers this doesn't mess |
|
85
|
|
|
|
|
|
|
# something up, particularly w/ parent/child sharing issues...) |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
my $request_class = $bc->{request_class}; |
|
88
|
|
|
|
|
|
|
my $R = $request_class->instance; |
|
89
|
|
|
|
|
|
|
$R->{stash_class} = $stash_class; |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
# The config object should now have all actions and SPOPS definitions |
|
92
|
|
|
|
|
|
|
# read in, so run any necessary configuration options |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
my $init_class = $class->finalize_configuration({ config => $C }); |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
# Tell OpenInteract::Request to setup aliases if they haven't already |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
if ( $p->{alias_init} ) { |
|
99
|
|
|
|
|
|
|
$request_class->setup_aliases; |
|
100
|
|
|
|
|
|
|
} |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
# Initialize all the SPOPS object classes |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
if ( $p->{spops_init} ) { |
|
105
|
|
|
|
|
|
|
$class->initialize_spops({ config => $C, class => $init_class }); |
|
106
|
|
|
|
|
|
|
} |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
# Read in all the classes for all configured conductors |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
my @conductor_classes = (); |
|
111
|
|
|
|
|
|
|
foreach my $conductor ( keys %{ $C->{conductor} } ) { |
|
112
|
|
|
|
|
|
|
push @conductor_classes, $C->{conductor}{ $conductor }{class}; |
|
113
|
|
|
|
|
|
|
} |
|
114
|
|
|
|
|
|
|
$class->require_module({ class => \@conductor_classes }); |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
# Read in the modules referred to in the 'system_alias' key from |
|
117
|
|
|
|
|
|
|
# the configuration -- EXCEPT for anything beginning with the |
|
118
|
|
|
|
|
|
|
# website name since that's an SPOPS object and has already been |
|
119
|
|
|
|
|
|
|
# created |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
my @system_alias_classes = grep ! /^$bc->{website_name}/, values %{ $C->{system_alias} }; |
|
122
|
|
|
|
|
|
|
$class->require_module({ class => \@system_alias_classes }); |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
DEBUG && _w( 2, "Contents of INC: @INC" ); |
|
125
|
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
# All done! Return the configuration object so the user can |
|
127
|
|
|
|
|
|
|
# do whatever else is necessary |
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
return ( $init_class, $C ); |
|
130
|
|
|
|
|
|
|
} |
|
131
|
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub setup_static_environment_options { |
|
134
|
|
|
|
|
|
|
my ( $class, $usage, $options, $params ) = @_; |
|
135
|
|
|
|
|
|
|
$options ||= {}; |
|
136
|
|
|
|
|
|
|
my ( $OPT_website_dir ); |
|
137
|
|
|
|
|
|
|
$options->{'website_dir=s'} = \$OPT_website_dir; |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
# Get the options |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
GetOptions( %{ $options } ); |
|
142
|
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
if ( ! $OPT_website_dir and $ENV{OIWEBSITE} ) { |
|
144
|
|
|
|
|
|
|
warn "Using ($ENV{OIWEBSITE}) for 'website_dir'.\n"; |
|
145
|
|
|
|
|
|
|
$OPT_website_dir = $ENV{OIWEBSITE}; |
|
146
|
|
|
|
|
|
|
} |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
unless ( -d $OPT_website_dir ) { |
|
149
|
|
|
|
|
|
|
die "$usage\n Parameter 'website_dir' must refer to an OpenInteract website directory!\n"; |
|
150
|
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
return $class->setup_static_environment( $OPT_website_dir, undef, $params ); |
|
152
|
|
|
|
|
|
|
} |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
# Use this if you want to setup the OpenInteract environment outside |
|
156
|
|
|
|
|
|
|
# of the web application server -- just pass in the website directory! |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
sub setup_static_environment { |
|
159
|
|
|
|
|
|
|
my ( $class, $website_dir, $su_passwd, $params ) = @_; |
|
160
|
|
|
|
|
|
|
die "Directory ($website_dir) is not a valid directory!\n" unless ( -d $website_dir ); |
|
161
|
|
|
|
|
|
|
$params ||= {}; |
|
162
|
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
my $bc = $class->read_base_config({ dir => $website_dir }); |
|
164
|
|
|
|
|
|
|
unless ( $bc and ref $bc eq 'HASH' ) { |
|
165
|
|
|
|
|
|
|
die "No base configuration file found in website directory ($website_dir)" ; |
|
166
|
|
|
|
|
|
|
} |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
$class->create_temp_lib( $bc, $params->{temp_lib} ); |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
unshift @INC, $website_dir; |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
my ( $init, $C ) = $class->main_initialize({ base_config => $bc, |
|
173
|
|
|
|
|
|
|
alias_init => 1, |
|
174
|
|
|
|
|
|
|
spops_init => 1 }); |
|
175
|
|
|
|
|
|
|
my $REQUEST_CLASS = $C->{server_info}{request_class}; |
|
176
|
|
|
|
|
|
|
my $R = $REQUEST_CLASS->instance; |
|
177
|
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
$R->{stash_class} = $C->{server_info}{stash_class}; |
|
179
|
|
|
|
|
|
|
$R->stash( 'config', $C ); |
|
180
|
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
# If we were given the superuser password, retrieve the user and |
|
182
|
|
|
|
|
|
|
# check the password |
|
183
|
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
if ( $su_passwd ) { |
|
185
|
|
|
|
|
|
|
my $user = $R->user->fetch( 1, { skip_security => 1 }); |
|
186
|
|
|
|
|
|
|
die "Cannot create superuser!" unless ( $user ); |
|
187
|
|
|
|
|
|
|
unless ( $user->check_password( $su_passwd ) ) { |
|
188
|
|
|
|
|
|
|
die "Password for superuser does not match!\n"; |
|
189
|
|
|
|
|
|
|
} |
|
190
|
|
|
|
|
|
|
$R->{auth}{user} = $user; |
|
191
|
|
|
|
|
|
|
} |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
return $R; |
|
194
|
|
|
|
|
|
|
} |
|
195
|
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
# Slimmed down initialization procedure -- just do everything |
|
199
|
|
|
|
|
|
|
# necessary to read the config and set various values there |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
sub create_config { |
|
202
|
|
|
|
|
|
|
my ( $class, $p ) = @_; |
|
203
|
|
|
|
|
|
|
my $bc = $p->{base_config} || |
|
204
|
|
|
|
|
|
|
$class->read_base_config({ filename => $p->{base_config_file}, |
|
205
|
|
|
|
|
|
|
website_dir => $p->{website_dir} }); |
|
206
|
|
|
|
|
|
|
return undef unless ( $bc ); |
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
# Create the configuration file and set the base directory as configured; |
|
209
|
|
|
|
|
|
|
# also set other important classes from the config |
|
210
|
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
my $config_file = join( '/', $bc->{website_dir}, |
|
212
|
|
|
|
|
|
|
$bc->{config_dir}, $bc->{config_file} ); |
|
213
|
|
|
|
|
|
|
my $C = eval { OpenInteract::Config->instance( $bc->{config_type}, $config_file ) }; |
|
214
|
|
|
|
|
|
|
if ( $@ ) { |
|
215
|
|
|
|
|
|
|
die "Cannot read configuration file! Error: $@\n"; |
|
216
|
|
|
|
|
|
|
} |
|
217
|
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
# This information will be set for the life of the config object, |
|
219
|
|
|
|
|
|
|
# which should be as long as the apache child is alive if we're using |
|
220
|
|
|
|
|
|
|
# mod_perl, and will be set in the returned config object in any case |
|
221
|
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
$C->{dir}{base} = $bc->{website_dir}; |
|
223
|
|
|
|
|
|
|
$C->{dir}{interact} = $bc->{base_dir}; |
|
224
|
|
|
|
|
|
|
$C->{server_info}{request_class} = $bc->{request_class}; |
|
225
|
|
|
|
|
|
|
$C->{server_info}{stash_class} = $bc->{stash_class}; |
|
226
|
|
|
|
|
|
|
$C->{server_info}{website_name} = $bc->{website_name}; |
|
227
|
|
|
|
|
|
|
return $C; |
|
228
|
|
|
|
|
|
|
} |
|
229
|
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
# Method to copy all .pm files from all packages in a website to a |
|
232
|
|
|
|
|
|
|
# separate directory -- if it currently exists we clear it out first. |
|
233
|
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
sub create_temp_lib { |
|
235
|
|
|
|
|
|
|
my ( $class, $base_config, $opt ) = @_; |
|
236
|
|
|
|
|
|
|
$opt ||= ''; |
|
237
|
|
|
|
|
|
|
my $site_dir = $base_config->{website_dir}; |
|
238
|
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
my $lib_dir = $base_config->{templib_dir} |
|
240
|
|
|
|
|
|
|
|| "$site_dir/$TEMP_LIB_DIR"; |
|
241
|
|
|
|
|
|
|
unshift @INC, $lib_dir; |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
if ( -d $lib_dir and $opt eq 'lazy' ) { |
|
244
|
|
|
|
|
|
|
DEBUG && _w( 1, "Temp lib dir [$lib_dir] already exists and we're lazy;", |
|
245
|
|
|
|
|
|
|
"not copying modules to temp lib dir" ); |
|
246
|
|
|
|
|
|
|
return []; |
|
247
|
|
|
|
|
|
|
} |
|
248
|
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
File::Path::rmtree( $lib_dir ) if ( -d $lib_dir ); |
|
250
|
|
|
|
|
|
|
mkdir( $lib_dir, 0777 ); |
|
251
|
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
my $site_repos = $REPOS_CLASS->fetch( undef, |
|
253
|
|
|
|
|
|
|
{ directory => $base_config->{website_dir} } ); |
|
254
|
|
|
|
|
|
|
my $packages = $site_repos->fetch_all_packages(); |
|
255
|
|
|
|
|
|
|
my ( @all_files ); |
|
256
|
|
|
|
|
|
|
foreach my $package ( @{ $packages } ) { |
|
257
|
|
|
|
|
|
|
DEBUG && _w( 2, "Trying to copy files for package $package->{name}" ); |
|
258
|
|
|
|
|
|
|
my $files_copied = $PKG_CLASS->copy_modules( $package, $lib_dir ); |
|
259
|
|
|
|
|
|
|
push @all_files, @{ $files_copied }; |
|
260
|
|
|
|
|
|
|
} |
|
261
|
|
|
|
|
|
|
DEBUG && _w( 3, "Copied ", scalar @all_files, " module files to [$lib_dir]" ); |
|
262
|
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
# Now change permissions so all the files and directories are |
|
264
|
|
|
|
|
|
|
# world-everything, letting the process's umask kick in |
|
265
|
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
chmod( 0666, @all_files ); |
|
267
|
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
my %tmp_dirs = map { $_ => 1 } map { dirname( $_ ) } @all_files; |
|
269
|
|
|
|
|
|
|
chmod( 0777, keys %tmp_dirs ); |
|
270
|
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
return \@all_files; |
|
272
|
|
|
|
|
|
|
} |
|
273
|
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
sub read_package_list { |
|
276
|
|
|
|
|
|
|
my ( $class, $p ) = @_; |
|
277
|
|
|
|
|
|
|
return [] unless ( $p->{filename} or $p->{config} ); |
|
278
|
|
|
|
|
|
|
my $filename = $p->{filename} || |
|
279
|
|
|
|
|
|
|
join( '/', $p->{config}->get_dir( 'config' ), $p->{config}{package_list} ); |
|
280
|
|
|
|
|
|
|
open( PKG, $filename ) || die "Cannot open package list ($filename): $!"; |
|
281
|
|
|
|
|
|
|
my @packages = (); |
|
282
|
|
|
|
|
|
|
while ( ) { |
|
283
|
|
|
|
|
|
|
chomp; |
|
284
|
|
|
|
|
|
|
next if /^\s*\#/; |
|
285
|
|
|
|
|
|
|
next if /^\s*$/; |
|
286
|
|
|
|
|
|
|
s/^\s*//; |
|
287
|
|
|
|
|
|
|
s/\s*$//; |
|
288
|
|
|
|
|
|
|
push @packages, $_; |
|
289
|
|
|
|
|
|
|
} |
|
290
|
|
|
|
|
|
|
close( PKG ); |
|
291
|
|
|
|
|
|
|
return \@packages; |
|
292
|
|
|
|
|
|
|
} |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
# simple key-value config file |
|
297
|
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
sub read_base_config { |
|
299
|
|
|
|
|
|
|
my ( $class, $p ) = @_; |
|
300
|
|
|
|
|
|
|
unless ( $p->{filename} ) { |
|
301
|
|
|
|
|
|
|
my $dir = $p->{dir} || $p->{website_dir}; |
|
302
|
|
|
|
|
|
|
if ( $dir ) { |
|
303
|
|
|
|
|
|
|
$p->{filename} = $class->create_base_config_filename( $dir ); |
|
304
|
|
|
|
|
|
|
} |
|
305
|
|
|
|
|
|
|
} |
|
306
|
|
|
|
|
|
|
return undef unless ( -f $p->{filename} ); |
|
307
|
|
|
|
|
|
|
open( CONF, $p->{filename} ) || die "$!\n"; |
|
308
|
|
|
|
|
|
|
my $vars = {}; |
|
309
|
|
|
|
|
|
|
while ( ) { |
|
310
|
|
|
|
|
|
|
chomp; |
|
311
|
|
|
|
|
|
|
DEBUG && _w( 1, "Config line read: $_" ); |
|
312
|
|
|
|
|
|
|
next if ( /^\s*\#/ ); |
|
313
|
|
|
|
|
|
|
next if ( /^\s*$/ ); |
|
314
|
|
|
|
|
|
|
s/^\s*//; |
|
315
|
|
|
|
|
|
|
s/\s*$//; |
|
316
|
|
|
|
|
|
|
my ( $var, $value ) = split /\s+/, $_, 2; |
|
317
|
|
|
|
|
|
|
$vars->{ $var } = $value; |
|
318
|
|
|
|
|
|
|
} |
|
319
|
|
|
|
|
|
|
return $vars; |
|
320
|
|
|
|
|
|
|
} |
|
321
|
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
sub create_base_config_filename { |
|
323
|
|
|
|
|
|
|
my ( $class, $dir ) = @_; |
|
324
|
|
|
|
|
|
|
return join( '/', $dir, 'conf', 'base.conf' ); |
|
325
|
|
|
|
|
|
|
} |
|
326
|
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
# Params: |
|
328
|
|
|
|
|
|
|
# filename - file with modules to read, one per line (skip blanks, commented lines) |
|
329
|
|
|
|
|
|
|
# class - arrayref of classes to require |
|
330
|
|
|
|
|
|
|
# (pick one) |
|
331
|
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
sub require_module { |
|
333
|
|
|
|
|
|
|
my ( $class, $p ) = @_; |
|
334
|
|
|
|
|
|
|
my @success = (); |
|
335
|
|
|
|
|
|
|
if ( $p->{filename} ) { |
|
336
|
|
|
|
|
|
|
DEBUG && _w( 1, "Trying to open file $p->{filename}" ); |
|
337
|
|
|
|
|
|
|
return [] unless ( -f $p->{filename} ); |
|
338
|
|
|
|
|
|
|
open( MOD, $p->{filename} ) || die "Cannot open $p->{filename}: $!"; |
|
339
|
|
|
|
|
|
|
while ( ) { |
|
340
|
|
|
|
|
|
|
next if ( /^\s*$/ ); |
|
341
|
|
|
|
|
|
|
next if ( /^\s*\#/ ); |
|
342
|
|
|
|
|
|
|
chomp; |
|
343
|
|
|
|
|
|
|
DEBUG && _w( 1, "Trying to require $_" ); |
|
344
|
|
|
|
|
|
|
eval "require $_"; |
|
345
|
|
|
|
|
|
|
if ( $@ ) { _w( 0, sprintf( " --require error: %-40s: %s", $_, $@ ) ) } |
|
346
|
|
|
|
|
|
|
else { push @success, $_ } |
|
347
|
|
|
|
|
|
|
} |
|
348
|
|
|
|
|
|
|
close( MOD ); |
|
349
|
|
|
|
|
|
|
} |
|
350
|
|
|
|
|
|
|
elsif ( $p->{class} ) { |
|
351
|
|
|
|
|
|
|
$p->{class} = [ $p->{class} ] unless ( ref $p->{class} eq 'ARRAY' ); |
|
352
|
|
|
|
|
|
|
foreach ( @{ $p->{class} } ) { |
|
353
|
|
|
|
|
|
|
DEBUG && _w( 1, "Trying to require class ($_)" ); |
|
354
|
|
|
|
|
|
|
eval "require $_"; |
|
355
|
|
|
|
|
|
|
if ( $@ ) { _w( 0, sprintf( " --require error: %-40s (from %s): %s", $_, $p->{pkg_link}{$_}, $@ ) ) } |
|
356
|
|
|
|
|
|
|
else { push @success, $_ } |
|
357
|
|
|
|
|
|
|
} |
|
358
|
|
|
|
|
|
|
} |
|
359
|
|
|
|
|
|
|
return \@success; |
|
360
|
|
|
|
|
|
|
} |
|
361
|
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
# Params: |
|
365
|
|
|
|
|
|
|
# config = config object |
|
366
|
|
|
|
|
|
|
# package = name of package |
|
367
|
|
|
|
|
|
|
# package_dir = arrayref of base package directories (optional, read from config if not passed) |
|
368
|
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
sub process_package { |
|
370
|
|
|
|
|
|
|
my ( $class, $pkg_info, $CONF ) = @_; |
|
371
|
|
|
|
|
|
|
return undef unless ( $pkg_info ); |
|
372
|
|
|
|
|
|
|
return undef unless ( $CONF ); |
|
373
|
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
my $pkg_name = join( '-', $pkg_info->{name}, $pkg_info->{version} ); |
|
375
|
|
|
|
|
|
|
DEBUG && _w( 1, "Trying to process package ($pkg_name)" ); |
|
376
|
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
my $site_pkg_dir = join( '/', $pkg_info->{website_dir}, $pkg_info->{package_dir} ); |
|
378
|
|
|
|
|
|
|
my $base_pkg_dir = join( '/', $pkg_info->{base_dir}, $pkg_info->{package_dir} ); |
|
379
|
|
|
|
|
|
|
DEBUG && _w( 1, "Pkg dirs: ($base_pkg_dir, $site_pkg_dir) for $pkg_name" ); |
|
380
|
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
# Plow through the directories and find the module listings (to |
|
382
|
|
|
|
|
|
|
# include), action config (to parse and set) and the SPOPS config (to |
|
383
|
|
|
|
|
|
|
# parse and set). Base package first so its info can be overridden. |
|
384
|
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
foreach my $package_dir ( $base_pkg_dir, $site_pkg_dir ) { |
|
386
|
|
|
|
|
|
|
my $conf_pkg_dir = "$package_dir/conf"; |
|
387
|
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
# If the package does not have a 'list_module.dat', that's ok and the |
|
389
|
|
|
|
|
|
|
# 'require_module' class method will simply return an empty list. |
|
390
|
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
$class->require_module({ filename => "$conf_pkg_dir/list_module.dat" }); |
|
392
|
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
# Read in the 'action' information and set in the config object |
|
394
|
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
$class->read_action_definition({ filename => "$conf_pkg_dir/action.perl", |
|
396
|
|
|
|
|
|
|
config => $CONF, |
|
397
|
|
|
|
|
|
|
package => $pkg_info }); |
|
398
|
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
# Read in the SPOPS information and set in the config object; note |
|
400
|
|
|
|
|
|
|
# that we cannot *process* the SPOPS config yet because we must be |
|
401
|
|
|
|
|
|
|
# able to relate SPOPS objects, which cannot be done until all the |
|
402
|
|
|
|
|
|
|
# definitions are read in. (Yes, we could use 'map' here and above, |
|
403
|
|
|
|
|
|
|
# but it's confusing to people first reading the code) |
|
404
|
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
$class->read_spops_definition({ filename => "$conf_pkg_dir/spops.perl", |
|
406
|
|
|
|
|
|
|
config => $CONF, |
|
407
|
|
|
|
|
|
|
package => $pkg_info }); |
|
408
|
|
|
|
|
|
|
} |
|
409
|
|
|
|
|
|
|
} |
|
410
|
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
# Read in the action config info and set the information in the CONFIG |
|
414
|
|
|
|
|
|
|
# object. note that we overwrite whatever information is in the CONFIG |
|
415
|
|
|
|
|
|
|
# object -- this is a feature, not a bug, since it allows the base |
|
416
|
|
|
|
|
|
|
# installation to define lots of information and the website to only |
|
417
|
|
|
|
|
|
|
# override what it needs. |
|
418
|
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
# Also save the key under which this was retrieved under 'key' |
|
420
|
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
sub read_action_definition { |
|
422
|
|
|
|
|
|
|
my ( $class, $p ) = @_; |
|
423
|
|
|
|
|
|
|
DEBUG && _w( 1, "Reading action definitions from ($p->{filename})" ); |
|
424
|
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
# $CONF is easier to read and more consistent |
|
426
|
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
my $CONF = $p->{config}; |
|
428
|
|
|
|
|
|
|
my $action_info = eval { $class->read_perl_file({ filename => $p->{filename} }) }; |
|
429
|
|
|
|
|
|
|
return undef unless ( $action_info ); |
|
430
|
|
|
|
|
|
|
my @class_list = (); |
|
431
|
|
|
|
|
|
|
foreach my $action_key ( keys %{ $action_info } ) { |
|
432
|
|
|
|
|
|
|
$CONF->{action}{ $action_key }{key} = $action_key; |
|
433
|
|
|
|
|
|
|
foreach my $action_conf ( keys %{ $action_info->{ $action_key } } ) { |
|
434
|
|
|
|
|
|
|
$CONF->{action}{ $action_key }{ $action_conf } = |
|
435
|
|
|
|
|
|
|
$action_info->{ $action_key }{ $action_conf }; |
|
436
|
|
|
|
|
|
|
} |
|
437
|
|
|
|
|
|
|
if ( ref $p->{package} ) { |
|
438
|
|
|
|
|
|
|
$CONF->{action}{ $action_key }{package_name} = $p->{package}{name}; |
|
439
|
|
|
|
|
|
|
$CONF->{action}{ $action_key }{package_version} = $p->{package}{version}; |
|
440
|
|
|
|
|
|
|
} |
|
441
|
|
|
|
|
|
|
} |
|
442
|
|
|
|
|
|
|
} |
|
443
|
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
# See comments in read_action_definition |
|
447
|
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
sub read_spops_definition { |
|
449
|
|
|
|
|
|
|
my ( $class, $p ) = @_; |
|
450
|
|
|
|
|
|
|
DEBUG && _w( 1, "Reading SPOPS definitions from ($p->{filename})" ); |
|
451
|
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
# $CONF is easier to read and more consistent |
|
453
|
|
|
|
|
|
|
my $CONF = $p->{config}; |
|
454
|
|
|
|
|
|
|
my $spops_info = eval { $class->read_perl_file({ filename => $p->{filename} }) }; |
|
455
|
|
|
|
|
|
|
return undef unless ( $spops_info ); |
|
456
|
|
|
|
|
|
|
my @class_list = (); |
|
457
|
|
|
|
|
|
|
foreach my $spops_key ( keys %{ $spops_info } ) { |
|
458
|
|
|
|
|
|
|
$CONF->{SPOPS}{ $spops_key }{key} = $spops_key; |
|
459
|
|
|
|
|
|
|
foreach my $spops_conf ( keys %{ $spops_info->{ $spops_key } } ) { |
|
460
|
|
|
|
|
|
|
$CONF->{SPOPS}{ $spops_key }{ $spops_conf } = |
|
461
|
|
|
|
|
|
|
$spops_info->{ $spops_key }{ $spops_conf }; |
|
462
|
|
|
|
|
|
|
} |
|
463
|
|
|
|
|
|
|
if ( ref $p->{package} ) { |
|
464
|
|
|
|
|
|
|
$CONF->{SPOPS}{ $spops_key }{package_name} = $p->{package}{name}; |
|
465
|
|
|
|
|
|
|
$CONF->{SPOPS}{ $spops_key }{package_version} = $p->{package}{version}; |
|
466
|
|
|
|
|
|
|
} |
|
467
|
|
|
|
|
|
|
} |
|
468
|
|
|
|
|
|
|
} |
|
469
|
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
# Read in a perl structure (probably generated by Data::Dumper) from a |
|
472
|
|
|
|
|
|
|
# file and return the actual structure. We should probably use |
|
473
|
|
|
|
|
|
|
# SPOPS::HashFile for this for consistency... |
|
474
|
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
sub read_perl_file { |
|
476
|
|
|
|
|
|
|
my ( $class, $p ) = @_; |
|
477
|
|
|
|
|
|
|
return undef unless ( -f $p->{filename} ); |
|
478
|
|
|
|
|
|
|
eval { open( INFO, $p->{filename} ) || die $! }; |
|
479
|
|
|
|
|
|
|
if ( $@ ) { |
|
480
|
|
|
|
|
|
|
warn "Cannot open config file for evaluation ($p->{filename}): $@ "; |
|
481
|
|
|
|
|
|
|
return undef; |
|
482
|
|
|
|
|
|
|
} |
|
483
|
|
|
|
|
|
|
local $/ = undef; |
|
484
|
|
|
|
|
|
|
no strict; |
|
485
|
|
|
|
|
|
|
my $info = ; |
|
486
|
|
|
|
|
|
|
close( INFO ); |
|
487
|
|
|
|
|
|
|
my $data = eval $info; |
|
488
|
|
|
|
|
|
|
if ( $@ ) { |
|
489
|
|
|
|
|
|
|
die "Cannot read data structure! from $p->{filename}\nError: $@"; |
|
490
|
|
|
|
|
|
|
} |
|
491
|
|
|
|
|
|
|
return $data; |
|
492
|
|
|
|
|
|
|
} |
|
493
|
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
# Everything has been read in, now just finalize aliases and so on |
|
496
|
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
sub finalize_configuration { |
|
498
|
|
|
|
|
|
|
my ( $class, $p ) = @_; |
|
499
|
|
|
|
|
|
|
my $CONF = $p->{config}; |
|
500
|
|
|
|
|
|
|
my $REQUEST_CLASS = $CONF->{server_info}{request_class}; |
|
501
|
|
|
|
|
|
|
my $STASH_CLASS = $CONF->{server_info}{stash_class}; |
|
502
|
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
# Create all the packages and subroutines on the fly as necessary |
|
504
|
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
DEBUG && _w( 1, "Trying to configure SPOPS classes with SPOPS::ClassFactory" ); |
|
506
|
|
|
|
|
|
|
my $init_class = SPOPS::ClassFactory->create( $CONF->{SPOPS} ); |
|
507
|
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
# Setup the default responses, template classes, etc. for all the |
|
509
|
|
|
|
|
|
|
# actions read in. |
|
510
|
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
$CONF->flatten_action_config; |
|
512
|
|
|
|
|
|
|
DEBUG && _w( 2, "Config: \n", Dumper( $CONF ) ); |
|
513
|
|
|
|
|
|
|
DEBUG && _w( 1, "Configuration read into Request ok." ); |
|
514
|
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
# We also want to go through each alias in the 'SPOPS' config key |
|
516
|
|
|
|
|
|
|
# and setup aliases to the proper class within our Request class; so |
|
517
|
|
|
|
|
|
|
# $request_alias is just a reference to where we'll actually be storing |
|
518
|
|
|
|
|
|
|
# this stuff |
|
519
|
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
my $request_alias = $REQUEST_CLASS->ALIAS; |
|
521
|
|
|
|
|
|
|
DEBUG && _w( 1, "Setting up SPOPS aliases" ); |
|
522
|
|
|
|
|
|
|
foreach my $init_alias ( keys %{ $CONF->{SPOPS} } ) { |
|
523
|
|
|
|
|
|
|
next if ( $init_alias =~ /^_/ ); |
|
524
|
|
|
|
|
|
|
my $info = $CONF->{SPOPS}{ $init_alias }; |
|
525
|
|
|
|
|
|
|
my $class_alias = $info->{class}; |
|
526
|
|
|
|
|
|
|
my @alias_list = ( $init_alias ); |
|
527
|
|
|
|
|
|
|
push @alias_list, @{ $info->{alias} } if ( $info->{alias} ); |
|
528
|
|
|
|
|
|
|
foreach my $alias ( @alias_list ) { |
|
529
|
|
|
|
|
|
|
DEBUG && _w( 1, "Tag $alias in $STASH_CLASS to be $class_alias" ); |
|
530
|
|
|
|
|
|
|
$request_alias->{ $alias }{ $STASH_CLASS } = $class_alias; |
|
531
|
|
|
|
|
|
|
} |
|
532
|
|
|
|
|
|
|
} |
|
533
|
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
DEBUG && _w( 1, "Setting up System aliases" ); |
|
535
|
|
|
|
|
|
|
foreach my $alias ( keys %{ $CONF->{system_alias} } ) { |
|
536
|
|
|
|
|
|
|
$request_alias->{ $alias }{ $STASH_CLASS } = $CONF->{system_alias}{ $alias }; |
|
537
|
|
|
|
|
|
|
} |
|
538
|
|
|
|
|
|
|
DEBUG && _w( 1, "Setup object and system aliases ok" ); |
|
539
|
|
|
|
|
|
|
return $init_class; |
|
540
|
|
|
|
|
|
|
} |
|
541
|
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
# Plow through a list of classes and call the class_initialize |
|
544
|
|
|
|
|
|
|
# method on each; ok to call OpenInteract::Startup->initialize_spops( ... ) |
|
545
|
|
|
|
|
|
|
# from the mod_perl child init handler |
|
546
|
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
sub initialize_spops { |
|
548
|
|
|
|
|
|
|
my ( $class, $p ) = @_; |
|
549
|
|
|
|
|
|
|
return undef unless ( ref $p->{class} ); |
|
550
|
|
|
|
|
|
|
return undef unless ( ref $p->{config} ); |
|
551
|
|
|
|
|
|
|
my @success = (); |
|
552
|
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
# Just cycle through and initialize each |
|
554
|
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
foreach my $spops_class ( @{ $p->{class} } ) { |
|
556
|
|
|
|
|
|
|
eval { $spops_class->class_initialize( $p->{config} ); }; |
|
557
|
|
|
|
|
|
|
push @success, $spops_class unless ( $@ ); |
|
558
|
|
|
|
|
|
|
DEBUG && _w( 1, sprintf( "%-40s: %-30s","init: $spops_class", ( $@ ) ? $@ : 'ok' ) ); |
|
559
|
|
|
|
|
|
|
} |
|
560
|
|
|
|
|
|
|
return \@success; |
|
561
|
|
|
|
|
|
|
} |
|
562
|
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
# Do any global overrides for both SPOPS and the action table entries. |
|
565
|
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
sub _process_global_overrides { |
|
567
|
|
|
|
|
|
|
my ( $class, $config ) = @_; |
|
568
|
|
|
|
|
|
|
my $override_spops_file = join( '/', $config->{dir}{base}, |
|
569
|
|
|
|
|
|
|
$config->{override}{spops_file} ); |
|
570
|
|
|
|
|
|
|
my $override_action_file = join( '/', $config->{dir}{base}, |
|
571
|
|
|
|
|
|
|
$config->{override}{action_file} ); |
|
572
|
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
if ( -f $override_spops_file ) { |
|
574
|
|
|
|
|
|
|
my $override_spops = OpenInteract::Config::GlobalOverride->new( |
|
575
|
|
|
|
|
|
|
{ filename => $override_spops_file } ); |
|
576
|
|
|
|
|
|
|
$override_spops->apply_rules( $config->{SPOPS} ); |
|
577
|
|
|
|
|
|
|
} |
|
578
|
|
|
|
|
|
|
if ( -f $override_action_file ) { |
|
579
|
|
|
|
|
|
|
my $override_action = OpenInteract::Config::GlobalOverride->new( |
|
580
|
|
|
|
|
|
|
{ filename => $override_action_file } ); |
|
581
|
|
|
|
|
|
|
$override_action->apply_rules( $config->{action} ); |
|
582
|
|
|
|
|
|
|
} |
|
583
|
|
|
|
|
|
|
} |
|
584
|
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
sub _require_extra_classes { |
|
587
|
|
|
|
|
|
|
my ( $class, $config ) = @_; |
|
588
|
|
|
|
|
|
|
my ( %require_class ); |
|
589
|
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
my $action_require = $class->_find_extra_action_classes( $config ); |
|
591
|
|
|
|
|
|
|
my $spops_require = $class->_find_extra_spops_classes( $config ); |
|
592
|
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
# Read in all the classes specified by the packages |
|
594
|
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
my $successful_action = $class->require_module({ |
|
596
|
|
|
|
|
|
|
class => [ keys %{ $action_require } ], |
|
597
|
|
|
|
|
|
|
pkg_link => $action_require }); |
|
598
|
|
|
|
|
|
|
if ( scalar @{ $successful_action } != scalar keys %{ $action_require } ) { |
|
599
|
|
|
|
|
|
|
my %all_tried = map { $_ => 1 } keys %{ $action_require }; |
|
600
|
|
|
|
|
|
|
delete $all_tried{ $_ } for ( @{ $successful_action } ); |
|
601
|
|
|
|
|
|
|
_w( 0, "Some action classes were not required: ", |
|
602
|
|
|
|
|
|
|
join( ', ', keys %all_tried ) ); |
|
603
|
|
|
|
|
|
|
} |
|
604
|
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
my $successful_spops = $class->require_module({ |
|
606
|
|
|
|
|
|
|
class => [ keys %{ $spops_require } ], |
|
607
|
|
|
|
|
|
|
pkg_link => $spops_require }); |
|
608
|
|
|
|
|
|
|
if ( scalar @{ $successful_spops } != scalar keys %{ $spops_require } ) { |
|
609
|
|
|
|
|
|
|
my %all_tried = map { $_ => 1 } keys %{ $spops_require }; |
|
610
|
|
|
|
|
|
|
delete $all_tried{ $_ } for ( @{ $successful_spops } ); |
|
611
|
|
|
|
|
|
|
_w( 0, "Some SPOPS classes were not required: ", |
|
612
|
|
|
|
|
|
|
join( ', ', keys %all_tried ) ); |
|
613
|
|
|
|
|
|
|
} |
|
614
|
|
|
|
|
|
|
} |
|
615
|
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
sub _find_extra_action_classes { |
|
618
|
|
|
|
|
|
|
my ( $class, $config ) = @_; |
|
619
|
|
|
|
|
|
|
my %map = (); |
|
620
|
|
|
|
|
|
|
my $action = $config->{action}; |
|
621
|
|
|
|
|
|
|
foreach my $key ( keys %{ $action } ) { |
|
622
|
|
|
|
|
|
|
next unless ( $key and $action->{ $key }); |
|
623
|
|
|
|
|
|
|
my $package = $action->{ $key }{package_name}; |
|
624
|
|
|
|
|
|
|
if ( $action->{ $key }{class} ) { |
|
625
|
|
|
|
|
|
|
$map{ $action->{ $key }{class} } = $package |
|
626
|
|
|
|
|
|
|
} |
|
627
|
|
|
|
|
|
|
if ( $action->{ $key }{filter} ) { |
|
628
|
|
|
|
|
|
|
if ( ref $action->{ $key }{filter} eq 'ARRAY' ) { |
|
629
|
|
|
|
|
|
|
$map{ $_ } = $package for ( @{ $action->{ $key }{filter} } ); |
|
630
|
|
|
|
|
|
|
} |
|
631
|
|
|
|
|
|
|
else { |
|
632
|
|
|
|
|
|
|
$map{ $action->{ $key }{filter} } = $package |
|
633
|
|
|
|
|
|
|
} |
|
634
|
|
|
|
|
|
|
} |
|
635
|
|
|
|
|
|
|
if ( $action->{ $key }{error} ) { |
|
636
|
|
|
|
|
|
|
if ( ref $action->{ $key }{error} eq 'ARRAY' ) { |
|
637
|
|
|
|
|
|
|
$map{ $_ } = $package for ( @{ $action->{ $key }{error} } ); |
|
638
|
|
|
|
|
|
|
} |
|
639
|
|
|
|
|
|
|
else { |
|
640
|
|
|
|
|
|
|
$map{ $action->{ $key }{error} } = $package; |
|
641
|
|
|
|
|
|
|
} |
|
642
|
|
|
|
|
|
|
} |
|
643
|
|
|
|
|
|
|
} |
|
644
|
|
|
|
|
|
|
return \%map; |
|
645
|
|
|
|
|
|
|
} |
|
646
|
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
sub _find_extra_spops_classes { |
|
649
|
|
|
|
|
|
|
my ( $class, $config ) = @_; |
|
650
|
|
|
|
|
|
|
my %map = (); |
|
651
|
|
|
|
|
|
|
my $spops = $config->{SPOPS}; |
|
652
|
|
|
|
|
|
|
foreach my $key ( keys %{ $spops } ) { |
|
653
|
|
|
|
|
|
|
next unless ( $key and $spops->{ $key }); |
|
654
|
|
|
|
|
|
|
my $package = $spops->{ $key }{package_name}; |
|
655
|
|
|
|
|
|
|
if ( ref $spops->{ $key }{isa} eq 'ARRAY' ) { |
|
656
|
|
|
|
|
|
|
map { $map{ $_ } = $package } @{ $spops->{ $key }{isa} }; |
|
657
|
|
|
|
|
|
|
} |
|
658
|
|
|
|
|
|
|
} |
|
659
|
|
|
|
|
|
|
return \%map; |
|
660
|
|
|
|
|
|
|
} |
|
661
|
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
sub _w { |
|
665
|
|
|
|
|
|
|
return unless ( DEBUG >= shift ); |
|
666
|
|
|
|
|
|
|
my ( $pkg, $file, $line ) = caller; |
|
667
|
|
|
|
|
|
|
my @ci = caller(1); |
|
668
|
|
|
|
|
|
|
warn "$ci[3] ($line) >> ", join( ' ', @_ ), "\n"; |
|
669
|
|
|
|
|
|
|
} |
|
670
|
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
1; |
|
672
|
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
__END__ |