File Coverage

blib/lib/ModPerl/ParamBuilder.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package ModPerl::ParamBuilder;
2             #####################################################################
3             #
4             # Module : ModPerl::ParamBuilder
5             # Author : Frank Wiles
6             #
7             # Description : This module is a wrapper that assists in making/using
8             # custom Apache directives easier for the most common
9             # use cases.
10             #
11             #####################################################################
12              
13 1     1   27686 use strict;
  1         3  
  1         35  
14 1     1   6 use warnings;
  1         1  
  1         30  
15 1     1   5 use vars qw( $VERSION );
  1         5  
  1         46  
16              
17 1     1   5 use Carp qw( croak );
  1         2  
  1         61  
18              
19 1     1   413 use Apache2::CmdParms ();
  0            
  0            
20             use Apache2::Module ();
21             use Apache2::ServerUtil ();
22              
23             ###########################################################
24             # Variables #
25             ###########################################################
26             $VERSION = '0.08';
27              
28             ###########################################################
29             # Methods #
30             ###########################################################
31              
32             #------------------------------------------------
33             # new( __PACKAGE__ )
34             #------------------------------------------------
35             # Object constructor
36             #------------------------------------------------
37             sub new {
38             my $class = shift;
39             my $package = shift;
40              
41             # For use when retrieving the configuration
42             if( !defined( $package ) and $class !~ /^ModPerl::ParamBuilder/o ) {
43             $package = $class;
44             }
45              
46             # Make sure we receive a package name
47             croak( 'No package defined in new() ' . caller . ' ' . $class )
48             if ( !defined( $package ) or $package eq '' );
49              
50             my $self = {};
51              
52             # In what namespace we are going to install these directives in
53             $$self{_calling_package} = $package;
54              
55             # Array to hold our directives
56             $$self{_directives} = [];
57              
58             # Objectify this hash :)
59             bless( $self, $class );
60              
61             return( $self );
62              
63             } # END new
64              
65             #------------------------------------------------
66             # _build_param
67             #------------------------------------------------
68             # This the main meat of this module. It builds
69             # up our @{ $self{_directives} } array that we
70             # pass to Apache2::Module::add() to actually
71             # install them
72             #------------------------------------------------
73             sub _build_param {
74             my $self = shift;
75             my $opts = shift;
76              
77             # Ensure we have some options and do some basic error checking
78             croak( 'No options passed to ModPerl::ParamBuilder::_build_param() ' )
79             if ( keys( %{$opts} ) < 1 );
80              
81             # Make sure we have a name
82             croak( ' \'name\' must be defined in order to build paramater ' )
83             if !exists( $$opts{name} );
84              
85             # Hash used in building the directives array
86             my $tmp_hash = {};
87             $$tmp_hash{ 'name' } = $$opts{name};
88              
89             # The hash key defaults to the name of the directive or
90             # the user can override it by passing a 'key' to use
91             if( !exists( $$opts{key} ) or $$opts{key} eq '' ) {
92             $$tmp_hash{ 'cmd_data' } = $$opts{name};
93             }
94             else {
95             $$tmp_hash{ 'cmd_data' } = $$opts{key};
96             }
97              
98             # Pass along our error message if there is one
99             if( exists( $$opts{err} ) ) {
100             $$tmp_hash{ 'errmsg' } = $$opts{err};
101             }
102              
103             # Determine what type of take we are
104             $$tmp_hash{ 'args_how' } = $self->_determine_take( $$opts{take} );
105              
106             # Set a function if we aren't given one explicitly
107             if( !exists($$opts{func}) or $$opts{func} eq '' ) {
108             $$tmp_hash{ 'func' } = $self->_determine_func($$tmp_hash{'args_how'});
109             }
110             else {
111             $$tmp_hash{ 'func' } = $$opts{func};
112             }
113              
114             # Store this directive for later loading
115             push( @{ $self->{_directives} }, $tmp_hash );
116              
117             } # END _build_param
118              
119             #------------------------------------------------
120             # _determine_take
121             #------------------------------------------------
122             # Figure out what options we need to take
123             #------------------------------------------------
124             sub _determine_take {
125             my $self = shift;
126             my $take = shift;
127             my $tmp_value = 'Apache2::Const::'; # Variable to return to caller
128              
129             # We've already explicitly set it, so don't bother trying to
130             # determine it
131             return( $take ) if ( $take and $take =~ /^Apache2::Const::/o );
132              
133             # Default to one argument
134             if( !defined( $take ) or $take eq '' ) {
135             return( $tmp_value . 'TAKE1' );
136             }
137              
138             # Translate any words to numbers
139             if( $take !~ /^\d+$/o ) {
140             $tmp_value .= 'TAKE1' if $take eq 'one';
141             $tmp_value .= 'TAKE2' if $take eq 'two';
142             $tmp_value .= 'TAKE3' if $take eq 'three';
143             $tmp_value .= 'TAKE12' if $take eq 'one_plus';
144             $tmp_value .= 'TAKE23' if $take eq 'two_plus';
145             $tmp_value .= 'TAKE123' if $take eq 'one_plus_two';
146             $tmp_value .= 'ITERATE' if $take eq 'list';
147             $tmp_value .= 'ITERATE2' if $take eq 'one_plus_list';
148             }
149             else {
150             $tmp_value .= 'TAKE' . $take;
151             }
152              
153             return( $tmp_value );
154              
155             } # END _determine_take
156              
157             #------------------------------------------------
158             # _determine_func
159             #------------------------------------------------
160             # This function determines which function we
161             # should use for processing the directive's
162             # values. It uses the already determined take
163             # for this. NOTE: This must be called after
164             # _determine_take to work properly
165             #------------------------------------------------
166             sub _determine_func {
167             my $self = shift;
168             my $arg = shift;
169              
170             # Make sure we're given an argument
171             croak( 'No argument given to _determine_func method' )
172             if ( !defined( $arg ) or $arg eq '' );
173              
174             # Clean up our argument for easier processing
175             $arg =~ s/^Apache2::Const:://o;
176              
177             return( __PACKAGE__ . '::Handle_TAKE1' ) if $arg eq 'TAKE1';
178             return( __PACKAGE__ . '::Handle_TAKE2' ) if $arg eq 'TAKE2';
179             return( __PACKAGE__ . '::Handle_TAKE3' ) if $arg eq 'TAKE3';
180             return( __PACKAGE__ . '::Handle_TAKE12' ) if $arg eq 'TAKE12';
181             return( __PACKAGE__ . '::Handle_TAKE23' ) if $arg eq 'TAKE23';
182             return( __PACKAGE__ . '::Handle_TAKE123' ) if $arg eq 'TAKE123';
183             return( __PACKAGE__ . '::Handle_ITERATE' ) if $arg eq 'ITERATE';
184             return( __PACKAGE__ . '::Handle_ITERATE2' ) if $arg eq 'ITERATE2';
185              
186             } # END _determine_func
187              
188             #------------------------------------------------
189             # param
190             #------------------------------------------------
191             # Build a directive based on user args
192             #------------------------------------------------
193             sub param {
194             my $self = shift;
195             my $arg = shift;
196              
197             # Make sure we're given something
198             croak( 'No arguments provided to param() method' )
199             if ( !$arg or $arg eq '' );
200              
201             # We either take a simple directive name or a hash of
202             # options for the directive
203             if( ref($arg) ne 'HASH' ) {
204             $self->_build_param( { name => $arg } );
205             }
206             else {
207             $self->_build_param( $arg );
208             }
209              
210             return;
211              
212             } # END param
213              
214             #------------------------------------------------
215             # no_arg
216             #------------------------------------------------
217             # This builds a directive that takes no arguments
218             # and is simply incremented when it is used
219             #------------------------------------------------
220             sub no_arg {
221             my $self = shift;
222             my $arg = shift;
223              
224             # Make sure we're given a name
225             croak( 'No arguments provided to no_arg() method' )
226             if ( !$arg or $arg eq '' );
227              
228             # Build it
229             my $tmp_hash = {};
230             $$tmp_hash{ 'take' } = 'Apache2::Const::NO_ARGS';
231             $$tmp_hash{ 'func' } = __PACKAGE__ . '::Handle_NO_ARGS';
232              
233             # Merge in any user overrides
234             if( ref( $arg ) eq 'HASH' ) {
235             $$tmp_hash{ 'name' } = $$arg{ 'name' };
236            
237             $$tmp_hash{ 'err' } = $$arg{ 'err' } if $$arg{ 'err' };
238             $$tmp_hash{ 'key' } = $$arg{ 'key' } if $$arg{ 'key' };
239             }
240             else {
241             $$tmp_hash{ 'name' } = $arg;
242             }
243              
244             # Actually build the parameter
245             $self->_build_param( $tmp_hash );
246              
247             } # END no_arg
248              
249             #------------------------------------------------
250             # on_off
251             #------------------------------------------------
252             # This builds a flag that is either On or Off
253             #------------------------------------------------
254             sub on_off {
255             my $self = shift;
256             my $arg = shift;
257              
258             # Make sure we're given something
259             croak( 'No arguments provided to on_off() method' )
260             if ( !$arg or $arg eq '' );
261              
262             # Build our our args for _build_param
263             my $tmp_hash = {};
264             $$tmp_hash{ 'take' } = 'Apache2::Const::FLAG';
265             $$tmp_hash{ 'func' } = $self->{_calling_package} . '::Handle_On_Off';
266              
267             if( ref( $arg ) eq 'HASH' ) {
268              
269             $$tmp_hash{ 'name' } = $$arg{'name'};
270             $$tmp_hash{ 'err' } = $$arg{'err'} if $$arg{'err'};
271             $$tmp_hash{ 'key' } = $$arg{'key'} if $$arg{'key'};
272              
273             }
274             else {
275             $$tmp_hash{ 'name' } = $arg;
276             }
277              
278             # Build the directive
279             $self->_build_param( $tmp_hash );
280              
281             } # END flag
282              
283             #------------------------------------------------
284             # yes_no
285             #------------------------------------------------
286             # This builds a simple argument that takes a
287             # Yes or No as it's argument
288             #------------------------------------------------
289             sub yes_no {
290             my $self = shift;
291             my $arg = shift;
292              
293             # Make sure we're given a name
294             croak( 'No arguments provided to yes_no() method' )
295             if ( !$arg or $arg eq '' );
296              
297             # Build our our args for _build_param
298             my $tmp_hash = {};
299             $$tmp_hash{ 'take' } = 'Apache2::Const::TAKE1';
300             $$tmp_hash{ 'func' } = $self->{_calling_package} . '::Handle_Yes_No';
301              
302             if( ref( $arg ) eq 'HASH' ) {
303              
304             $$tmp_hash{ 'name' } = $$arg{'name'};
305             $$tmp_hash{ 'err' } = $$arg{'err'} if $$arg{'err'};
306             $$tmp_hash{ 'key' } = $$arg{'key'} if $$arg{'key'};
307              
308             }
309             else {
310             $$tmp_hash{ 'name' } = $arg;
311             }
312              
313             # Build the directive
314             $self->_build_param( $tmp_hash );
315              
316             } # END yes_no
317              
318             #------------------------------------------------
319             # load
320             #------------------------------------------------
321             # Install the newly built directives
322             #------------------------------------------------
323             sub load {
324             my $self = shift;
325              
326             # Die if we don't have anything to build
327             if( scalar( @{ $self->{_directives} } ) < 1 ) {
328             croak "No Apache directives defined: $!";
329             }
330              
331             use Data::Dumper;
332             warn( "Loading..." );
333             warn( Dumper( $self->{_directives} ) );
334              
335             # Actually load them
336             Apache2::Module::add( $self->{_calling_package},
337             \@{ $self->{_directives} } );
338              
339             } # END load
340              
341             #------------------------------------------------
342             # get_config
343             #------------------------------------------------
344             # This method retrieves the configuration for
345             # this module
346             #------------------------------------------------
347             sub get_config {
348             my $self = shift;
349             my $r = shift;
350              
351             # Use the caller when retrieving from outside of the derived
352             # class
353             if( !defined($self) ) {
354             $self = caller;
355             }
356              
357             # Use the $r we are given, but if we're not given one
358             # attempt to get the global one, provided the user has
359             # +GlobalRequest on
360             if( !defined($r) ) {
361              
362             use Apache2::RequestUtil ();
363              
364             # Retrieve global request
365             $r = Apache2::RequestUtil->request or
366             croak 'No request object given to get_config() and '.
367             'PerlOptions +GlobalRequest not set, unable to '.
368             'retrieve configuration without request object'
369             }
370              
371             # Retrieve the actual configuration
372             no strict 'refs';
373             my $return_value = Apache2::Module::get_config(
374             $self->{_calling_package},
375             $r->server,
376             $r->per_dir_config );
377              
378             return( $return_value );
379              
380             } # END get_config
381              
382             #####################################################################
383             # Below are the functions used to process the arguments of the
384             # directives
385             #####################################################################
386              
387             #------------------------------------------------
388             # Handle_TAKE1
389             #------------------------------------------------
390             sub Handle_TAKE1 {
391             my ($self, $parms, $arg) = @_;
392              
393             $self->{ $parms->info } = $arg;
394              
395             } # END HANDLE_TAKE1
396              
397             #------------------------------------------------
398             # Handle_TAKE2
399             #------------------------------------------------
400             sub Handle_TAKE2 {
401             my ($self, $parms, $arg1, $arg2) = @_;
402              
403             $self->{ $parms->info } = { arg1 => $arg1, arg2 => $arg2 };
404              
405             } # END HANDLE_TAKE2
406              
407             #------------------------------------------------
408             # Handle_TAKE3
409             #------------------------------------------------
410             sub Handle_TAKE3 {
411             my ($self, $parms, $arg1, $arg2, $arg3) = @_;
412              
413             $self->{ $parms->info } = { arg1 => $arg1, arg2 => $arg2, arg3 => $arg3 };
414              
415             } # END HANDLE_TAKE3
416              
417             #------------------------------------------------
418             # Handle_TAKE12
419             #------------------------------------------------
420             sub Handle_TAKE12 {
421             my ($self, $parms, $arg1, $arg2) = @_;
422              
423             $self->{ $parms->info } = { arg1 => $arg1, arg2 => $arg2 };
424              
425             } # END HANDLE_TAKE12
426              
427             #------------------------------------------------
428             # Handle_TAKE23
429             #------------------------------------------------
430             sub Handle_TAKE23 {
431             my ($self, $parms, $arg1, $arg2, $arg3) = @_;
432              
433             $self->{ $parms->info } = { arg1 => $arg1, arg2 => $arg2, arg3 => $arg3 };
434              
435             } # END HANDLE_TAKE23
436              
437             #------------------------------------------------
438             # Handle_TAKE123
439             #------------------------------------------------
440             sub Handle_TAKE123 {
441             my ($self, $parms, $arg1, $arg2, $arg3) = @_;
442              
443             $self->{ $parms->info } = { arg1 => $arg1, arg2 => $arg2, arg3 => $arg3 };
444              
445             } # END HANDLE_TAKE123
446              
447             #------------------------------------------------
448             # Handle_ITERATE
449             #------------------------------------------------
450             # Handle a list
451             #------------------------------------------------
452             sub Handle_ITERATE {
453             my ($self, $parms, $arg) = @_;
454              
455             if( !exists( $self->{ $parms->info } ) ) {
456             $self->{ $parms->info } = [];
457             }
458              
459             push( @{ $self->{ $parms->info } }, $arg );
460              
461             } # END HANDLE_ITERATE
462              
463             #------------------------------------------------
464             # Handle_ITERATE2
465             #------------------------------------------------
466             # Handle a default and a list
467             #------------------------------------------------
468             sub Handle_ITERATE2 {
469             my ($self, $parms, $key, $val) = @_;
470              
471             push( @{ $self->{ $parms->info }{ $key } }, $val );
472              
473             } # END HANDLE_ITERATE2
474              
475             #------------------------------------------------
476             # Handle_NO_ARGS
477             #------------------------------------------------
478             sub Handle_NO_ARGS {
479             my ($self, $parms) = @_;
480              
481             $self->{ $parms->info }++;
482              
483             } # END HANDLE_NO_ARGS
484              
485             #------------------------------------------------
486             # Handle_On_Off
487             #------------------------------------------------
488             sub Handle_On_Off {
489             my ($self, $parms, $arg) = @_;
490              
491             $self->{ $parms->info } = $arg;
492              
493             } # END HANDLE_On_Off
494              
495             #------------------------------------------------
496             # Handle_Yes_No
497             #------------------------------------------------
498             sub Handle_Yes_No {
499             my ($self, $parms, $arg) = @_;
500              
501             if( $arg =~ /yes/io ) {
502             $arg = 1;
503             }
504             else {
505             $arg = 0;
506             }
507              
508             $self->{ $parms->info } = $arg;
509              
510             } # END HANDLE_Yes_No
511              
512             # EOF
513             1;
514              
515             __END__