File Coverage

blib/lib/AxKit2/Plugin.pm
Criterion Covered Total %
statement 24 105 22.8
branch 0 26 0.0
condition 0 11 0.0
subroutine 8 26 30.7
pod 7 10 70.0
total 39 178 21.9


line stmt bran cond sub pod time code
1             # Copyright 2001-2006 The Apache Software Foundation
2             #
3             # Licensed under the Apache License, Version 2.0 (the "License");
4             # you may not use this file except in compliance with the License.
5             # You may obtain a copy of the License at
6             #
7             # http://www.apache.org/licenses/LICENSE-2.0
8             #
9             # Unless required by applicable law or agreed to in writing, software
10             # distributed under the License is distributed on an "AS IS" BASIS,
11             # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12             # See the License for the specific language governing permissions and
13             # limitations under the License.
14             #
15              
16             # Base class for AxKit2 plugins
17              
18             package AxKit2::Plugin;
19              
20 9     9   44 use strict;
  9         19  
  9         268  
21 9     9   41 use warnings;
  9         16  
  9         183  
22              
23 9     9   4515 use AxKit2::Config;
  9         26  
  9         313  
24 9     9   6059 use AxKit2::Constants;
  9         25  
  9         1413  
25 9     9   11213 use Attribute::Handlers;
  9         58715  
  9         62  
26              
27             # more or less in the order they will fire
28             # DON'T FORGET - edit "AVAILABLE HOOKS" below.
29             our @hooks = qw(
30             logging connect pre_request post_read_request body_data uri_translation
31             mime_map access_control authentication authorization fixup write_body_data
32             xmlresponse response response_sent disconnect error
33             );
34             our %hooks = map { $_ => 1 } @hooks;
35              
36             sub new {
37 0     0 0   my $proto = shift;
38 0   0       my $class = ref($proto) || $proto;
39 0           bless ({}, $class);
40             }
41              
42             sub register_hook {
43 0     0 1   my ($self, $hook, $method, $unshift) = @_;
44            
45 0           $self->log(LOGDEBUG, "register_hook: $hook => $method");
46 0 0         die $self->plugin_name . " : Invalid hook: $hook" unless $hooks{$hook};
47            
48 0           push @{$self->{__hooks}{$hook}}, sub {
49 0     0     my $self = shift;
50 0           local $self->{_hook} = $hook;
51 0           local $self->{_client} = shift;
52 0           local $self->{_config} = shift;
53 0           $self->$method(@_);
54 0           };
55             }
56              
57             sub register_config {
58 0     0 0   my ($self, $key, $store) = @_;
59            
60 0           AxKit2::Config->add_config_param($key, \&AxKit2::Config::TAKEMANY, $store);
61             }
62              
63             our %validators;
64             sub Validate : ATTR(CODE) {
65 0     0 0 0 my ($package, $symbol, $referent, $attr, $data, $phase) = @_;
66 0         0 $validators{$referent} = $data;
67 9     9   3542 }
  9         27  
  9         46  
68              
69             # default configuration handler
70             our $AUTOLOAD;
71             sub AUTOLOAD {
72 0 0   0     die "Undefined subroutine &$AUTOLOAD called" unless $AUTOLOAD =~ m/::conf_[^:]*$/;
73 0           shift;
74 0           return @_;
75             }
76              
77             sub _set_config {
78 0     0     my ($self, $key, $config, @value) = @_;
79 9     9   3515 no strict 'refs';
  9         19  
  9         1076  
80 0           my $sub = "conf_$key";
81 0           $self->{_config} = $config;
82 0 0         @value = $self->$sub(@value) if $sub;
83 0           delete $self->{_config};
84 0 0         return if (!@value);
85 0           $config->notes($self->plugin_name.'::'.$key,@value);
86             }
87              
88             sub _register_config {
89 0     0     my $self = shift;
90 9     9   48 no strict 'refs';
  9         14  
  9         14280  
91 0           foreach my $key (keys %{*{ref($self)."::"}}) {
  0            
  0            
92 0 0 0       next unless $key =~ m/^conf_/ && $self->can($key);
93 0           my $sub = $self->can($key);
94 0   0       my $validator = $validators{$sub} || \&AxKit2::Config::TAKEMANY;
95 0 0         $validator = \&{"AxKit2::Config::$validator"} if (ref($validator) ne 'CODE');
  0            
96 0           $key =~ s/^conf_//;
97 0     0     AxKit2::Config->add_config_param($key, $validator, sub { $self->_set_config($key,@_) });
  0            
98             }
99             }
100              
101             sub _register {
102 0     0     my $self = shift;
103 0           $self->init();
104 0           $self->_register_config();
105 0           $self->_register_standard_hooks();
106 0           $self->register();
107             }
108              
109 0     0 1   sub init {
110             # implement in plugin
111             }
112              
113 0     0 1   sub register {
114             # implement in plugin
115             }
116              
117             sub config {
118 0     0 1   my $self = shift;
119 0 0         if (@_) {
120 0           my $key = shift;
121 0           return $self->{_config}->notes($self->plugin_name . "::$key", @_);
122             }
123 0           $self->{_config};
124             }
125              
126             sub client {
127 0     0 1   my $self = shift;
128 0 0         $self->{_client} || "AxKit2::Client";
129             }
130              
131             sub log {
132 0     0 1   my $self = shift;
133 0           my $level = shift;
134 0           my ($package) = caller;
135 0 0 0       if ($package eq __PACKAGE__ || !defined $self->{_hook}) {
136 0           $self->client->log($level, $self->plugin_name, " ", @_);
137             }
138             else {
139 0           $self->client->log($level, $self->plugin_name, " $self->{_hook} ", @_);
140             }
141             }
142              
143             sub _register_standard_hooks {
144 0     0     my $self = shift;
145            
146 0           for my $hook (@hooks) {
147 0           my $hooksub = "hook_$hook";
148 0           $hooksub =~ s/\W/_/g;
149 0 0         $self->register_hook( $hook, $hooksub ) if ($self->can($hooksub));
150             }
151             }
152              
153             sub hooks {
154 0     0 1   my $self = shift;
155 0           my $hook = shift;
156            
157 0 0         return $self->{__hooks}{$hook} ? @{$self->{__hooks}{$hook}} : ();
  0            
158             }
159              
160             sub _compile {
161 0     0     my ($class, $plugin, $package, $file) = @_;
162            
163 0           my $sub;
164 0 0         open F, $file or die "could not open $file: $!";
165             {
166 0           local $/ = undef;
  0            
167 0           $sub = ;
168             }
169 0           close F;
170              
171 0           my $line = "\n#line 0 $file\n";
172              
173 0           my $eval = join(
174             "\n",
175             "package $package;",
176             'use AxKit2::Constants;',
177             'use AxKit2::Processor;',
178             'use base "AxKit2::Plugin";',
179             'use strict;',
180             "sub plugin_name { qq[$plugin] }",
181             'sub hook_name { return shift->{_hook}; }',
182             $line,
183             $sub,
184             "\n", # last line comment without newline?
185             );
186              
187             #warn "eval: $eval";
188              
189 0           $eval =~ m/(.*)/s;
190 0           $eval = $1;
191              
192 0           eval $eval;
193 0 0         die "eval $@" if $@;
194             }
195              
196             1;
197              
198             __END__