home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / porting.pm < prev    next >
Encoding:
Perl POD Document  |  2004-09-17  |  5.9 KB  |  208 lines

  1. # Copyright 2003-2004 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. package Apache::porting;
  16.  
  17. use strict;
  18. use warnings FATAL => 'all';
  19.  
  20. use Carp 'croak';
  21.  
  22. use ModPerl::MethodLookup ();
  23. use Apache::ServerUtil;
  24.  
  25. use Apache::Const -compile => 'OK';
  26.  
  27. our $AUTOLOAD;
  28.  
  29. ### methods ###
  30. # handle:
  31. # - removed and replaced methods
  32. # - hinting the package names in which methods reside
  33.  
  34. my %avail_methods = map { $_ => 1 } 
  35.     (ModPerl::MethodLookup::avail_methods(),
  36.      ModPerl::MethodLookup::avail_methods_compat());
  37.  
  38. # XXX: unfortunately it doesn't seem to be possible to install
  39. # *UNIVERSAL::AUTOLOAD at the server startup, httpd segfaults,
  40. # child_init seems to be the first stage where it works.
  41. Apache->server->push_handlers(PerlChildInitHandler => \&porting_autoload);
  42.  
  43. sub porting_autoload {
  44.     *UNIVERSAL::AUTOLOAD = sub {
  45.         # This is a porting module, no compatibility layers are allowed in
  46.         # this zone
  47.         croak("Apache::porting can't be used with Apache::compat")
  48.             if exists $ENV{"Apache/compat.pm"};
  49.  
  50.         (my $method = $AUTOLOAD) =~ s/.*:://;
  51.  
  52.         # we skip DESTROY methods
  53.         return if $method eq 'DESTROY';
  54.  
  55.         # we don't handle methods that we don't know about
  56.         croak "Undefined subroutine $AUTOLOAD called"
  57.             unless defined $method && exists $avail_methods{$method};
  58.  
  59.         my ($hint, @modules) =
  60.             ModPerl::MethodLookup::lookup_method($method, @_);
  61.         $hint ||= "Can't find method $AUTOLOAD";
  62.         croak $hint;
  63.     };
  64.  
  65.     return Apache::OK;
  66. }
  67.  
  68. ### packages ###
  69. # handle:
  70. # - removed and replaced packages
  71.  
  72. my %packages = (
  73.      'Apache::Constants' => [qw(Apache::Const)],
  74.      'Apache::Table'     => [qw(APR::Table)],
  75.      'Apache::File'      => [qw(Apache::Response Apache::RequestRec)],
  76.      'Apache'            => [qw(ModPerl::Util Apache::Module)],
  77. );
  78.  
  79. BEGIN {
  80.     sub my_require {
  81.         my $package = $_[0];
  82.         $package =~ s|/|::|g;
  83.         $package =~ s|.pm$||;
  84.  
  85.         # this picks the original require (which could be overriden
  86.         # elsewhere, so we don't lose that) because we haven't
  87.         # overriden it yet
  88.         return require $_[0] unless $packages{$package};
  89.  
  90.         my $msg = "mod_perl 2.0 API doesn't include package '$package'.";
  91.         my @replacements = @{ $packages{$package}||[] };
  92.         if (@replacements) {
  93.             $msg .= " The package '$package' has moved to " .
  94.                 join " ", map qq/'$_'/, @replacements;
  95.         }
  96.         croak $msg;
  97.     };
  98.  
  99.     *CORE::GLOBAL::require = sub (*) { my_require($_[0])};
  100. }
  101.  
  102. 1;
  103.  
  104. =head1 NAME
  105.  
  106. Apache::porting -- a helper module for mod_perl 1.0 to mod_perl 2.0 porting
  107.  
  108.  
  109.  
  110. =head1 Synopsis
  111.  
  112.   # either add at the very beginning of startup.pl
  113.   use Apache2;
  114.   use Apache::porting;
  115.  
  116.   # or httpd.conf
  117.   PerlModule Apache2
  118.   PerlModule Apache::porting
  119.  
  120.   # now issue requests and look at the error_log file for hints
  121.  
  122.  
  123.  
  124.  
  125. =head1 Description
  126.  
  127. C<Apache::porting> helps to port mod_perl 1.0 code to run under
  128. mod_perl 2.0. It doesn't provide any back-compatibility functionality,
  129. however it knows trap calls to methods that are no longer in the
  130. mod_perl 2.0 API and tell what should be used instead if at all. If
  131. you attempts to use mod_perl 2.0 methods without first loading the
  132. modules that contain them, it will tell you which modules you need to
  133. load. Finally if your code tries to load modules that no longer exist
  134. in mod_perl 2.0 it'll also tell you what are the modules that should
  135. be used instead.
  136.  
  137. C<Apache::porting> communicates with users via the I<error_log>
  138. file. Everytime it traps a problem, it logs the solution (if it finds
  139. one) to the error log file. If you use this module coupled with
  140. C<L<Apache::Reload|docs::2.0::api::Apache::Reload>> you will be able
  141. to port your applications quickly without needing to restart the
  142. server on every modification.
  143.  
  144. It starts to work only when child process start and doesn't work for
  145. the code that gets loaded at the server startup. This limitation is
  146. explained in the L<Culprits|/Culprits> section.
  147.  
  148. It relies heavily on
  149. C<L<ModPerl::MethodLookup|docs::2.0::api::ModPerl::MethodLookup>>.
  150. which can also be used manually to lookup things.
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157. =head1 Culprits
  158.  
  159. C<Apache::porting> uses the C<UNIVERSAL::AUTOLOAD> function to provide
  160. its functionality. However it seems to be impossible to create
  161. C<UNIVERSAL::AUTOLOAD> at the server startup, Apache segfaults on
  162. restart. Therefore it performs the setting of C<UNIVERSAL::AUTOLOAD>
  163. only during the I<child_init> phase, when child processes start. As a
  164. result it can't help you with things that get preloaded at the server
  165. startup.
  166.  
  167. If you know how to resolve this problem, please let us know. To
  168. reproduce the problem try to use an earlier phase,
  169. e.g. C<PerlPostConfigHandler>:
  170.  
  171.   Apache->server->push_handlers(PerlPostConfigHandler => \&porting_autoload);
  172.  
  173. META: Though there is a better solution at work, which assigns
  174. AUTOLOAD for each class separately, instead of using UNIVERSAL. See
  175. the discussion on the dev list (hint: search the archive for EazyLife)
  176.  
  177.  
  178.  
  179.  
  180.  
  181. =head1 See Also
  182.  
  183. L<mod_perl 2.0 documentation|docs::2.0::index>.
  184.  
  185.  
  186.  
  187.  
  188.  
  189. =head1 Copyright
  190.  
  191. mod_perl 2.0 and its core modules are copyrighted under
  192. The Apache Software License, Version 2.0.
  193.  
  194.  
  195.  
  196.  
  197. =head1 Authors
  198.  
  199. L<The mod_perl development team and numerous
  200. contributors|about::contributors::people>.
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207. =cut
  208.