| 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__ |