Author: spadkins
Date: Mon Aug 30 14:40:44 2010
New Revision: 14365

Modified:
   p5ee/trunk/App-Context/lib/Apache/App.pm
   p5ee/trunk/App-Context/lib/App.pm

Log:
added necessary support for mod_perl

Modified: p5ee/trunk/App-Context/lib/Apache/App.pm
==============================================================================
--- p5ee/trunk/App-Context/lib/Apache/App.pm    (original)
+++ p5ee/trunk/App-Context/lib/Apache/App.pm    Mon Aug 30 14:40:44 2010
@@ -1,16 +1,18 @@
 
-#############################################################################
+######################################################################################
 ## $Id: App.pm 3666 2006-03-11 20:34:10Z spadkins $
-#############################################################################
+######################################################################################
 ## Note: Much of this code is borrowed from Apache::DBI
 ##       In doing so, I have made a half-hearted attempt to make this mod_perl 
1.X compatible.
 ##       However, I have never run it on mod_perl 1.X, only on mod_perl 2.X.
 ##       When someone debugs this on mod_perl 1.X, please let me know what you 
had to do to make it work.
-#############################################################################
+######################################################################################
 
 package Apache::App;
-$VERSION = (q$Revision: 3666 $ =~ /(\d[\d\.]*)/)[0];
 use strict;
+our $VERSION = (q$Revision: 3666 $ =~ /(\d[\d\.]*)/)[0];
+
+use base qw(ModPerl::RegistryCooker);
 
 use constant MP2 => (exists $ENV{MOD_PERL_API_VERSION} &&
                             $ENV{MOD_PERL_API_VERSION} == 2) ? 1 : 0;
@@ -27,6 +29,7 @@
         my $s = Apache2::ServerUtil->server;
         $s->push_handlers(PerlChildInitHandler => \&child_init_handler);
         $s->push_handlers(PerlChildExitHandler => \&child_exit_handler);
+        $s->push_handlers(PerlResponseHandler  => \&request_handler);
         $s->push_handlers(PerlCleanupHandler   => \&request_cleanup_handler);
     }
     elsif (defined $modperl::VERSION && $modperl::VERSION > 1 && 
$modperl::VERSION < 1.99) {
@@ -35,33 +38,184 @@
 
         Carp::carp("Apache.pm was not loaded\n")
               and return unless $INC{'Apache.pm'};
+
         if (Apache->can('push_handlers')) {
             Apache->push_handlers(PerlChildInitHandler => 
\&child_init_handler);
             Apache->push_handlers(PerlChildExitHandler => 
\&child_exit_handler);
+            Apache->push_handlers(PerlResponseHandler  => \&request_handler);
             Apache->push_handlers(PerlCleanupHandler   => 
\&request_cleanup_handler);
         }
     }
 }
 
 use Carp ();
+use App::Options;
 use App;
 
+##-BEGIN-OF-Apache::Registry-CODE-####################################################
+# The following section of code is lifted from ModPerl::Registry and modified.
+
+sub request_handler : method {
+    warn("$$ Apache::App::request_handler(@_)\n");
+    my $class = (@_ >= 2) ? shift : __PACKAGE__;
+    my $r = shift;
+
+    my $app_apache     = $class->new($r);
+
+    my $prog           = $app_apache->{FILENAME};   # (same as $r->filename())
+    $prog              =~ s/\\/\//g;
+    my $prog_dir       = $prog;
+    $prog_dir          =~ s!/[^/]+$!!;
+    my $prog_file      = $prog;
+    $prog_file         =~ s!.*/!!;
+
+    my $app            = App::Options->determine_app($ENV{PREFIX}, $prog_dir, 
$prog_file, $r->path_info());
+    $app_apache->prepare_context($app, $app_apache->{FILENAME});
+
+    # Then we run the request and return the result (Apache2::Const::OK)
+    my $request_result = $app_apache->default_handler();
+
+    warn("$$ Apache::App     app =[$app]\n");
+    warn("$$ Apache::App.REQ     =[$app_apache->{REQ}]\n");
+    warn("$$ Apache::App.URI     =[$app_apache->{URI}]\n");
+    warn("$$ Apache::App.FILENAME=[$app_apache->{FILENAME}]\n");
+
+    return $request_result;
+}
+
+my $parent_class = "ModPerl::RegistryCooker";
+my $self_class   = __PACKAGE__;
+
+# the following code:
+# - specifies package's behavior different from default of $parent class
+# - speeds things up by shortcutting @ISA search, so even if the
+#   default is used we still use the alias
+my %aliases = (
+    new             => "${parent_class}::new",
+    init            => "${parent_class}::init",
+    default_handler => "${parent_class}::default_handler",
+    run             => "${parent_class}::run",
+    can_compile     => "${parent_class}::can_compile",
+    make_namespace  => "${parent_class}::make_namespace",
+    namespace_root  => "${parent_class}::namespace_root",
+    namespace_from  => "${parent_class}::namespace_from_filename",
+    is_cached       => "${parent_class}::is_cached",
+    should_compile  => "${parent_class}::should_compile_if_modified",
+    flush_namespace => "${parent_class}::NOP",
+    cache_table     => "${parent_class}::cache_table_common",
+    cache_it        => "${parent_class}::cache_it",
+    read_script     => "${parent_class}::read_script",
+    shebang_to_perl => "${parent_class}::shebang_to_perl",
+    get_script_name => "${parent_class}::get_script_name",
+    chdir_file      => "${parent_class}::NOP",
+    get_mark_line   => "${parent_class}::get_mark_line",
+    compile         => "${parent_class}::compile",
+    error_check     => "${parent_class}::error_check",
+    strip_end_data_segment             => 
"${parent_class}::strip_end_data_segment",
+    convert_script_to_compiled_handler => 
"${parent_class}::convert_script_to_compiled_handler",
+);
+
+$self_class->install_aliases(\%aliases);
+
+##-END-OF-Apache::Registry-CODE-######################################################
+
+######################################################################################
+# Variables
+######################################################################################
+
 my (@service_on_init);             # services to be initialized when a new 
httpd child is created
-my %env = %ENV;
-my ($context);
+#my %env = %ENV;
+my (%options, %context);
+
+######################################################################################
+# This is supposed to be called in a startup script or in httpd.conf (<Perl> 
section).
+######################################################################################
+
+sub import {
+    # save global values initialized up until now
+    App->context() if (!$App::context);
+    Apache::App->save_context("main");
+}
 
-#############################################################################
-# This is supposed to be called in a startup script.
-# stores the data_source of all connections, which are supposed to be created
-# upon server startup, and creates a PerlChildInitHandler, which initiates
-# the connections.  Provide a handler which creates all connections during
-# server startup
-#############################################################################
+sub save_context {
+    my ($self, $app) = @_;
+    $options{$app} = { %App::options };
+    $context{$app} = $App::context;
+}
+
+sub restore_context {
+    my ($self, $app) = @_;
+
+    if ($options{$app}) {
+        %App::options = %{$options{$app}};
+    }
+    else {
+        %App::options = ();
+    }
+
+    if ($context{$app}) {
+        $App::context = $context{$app};
+    }
+    else {
+        $App::context = undef;
+    }
+}
+
+sub clear_context {
+    my ($self) = @_;
+    %App::options = ();
+    $App::context = undef;
+}
+
+#sub determine_app_from_request {
+#    my ($self, $r) = @_;
+#}
+
+######################################################################################
+# This is supposed to be called in a startup script or in httpd.conf (<Perl> 
section).
+######################################################################################
+
+sub prepare_context {
+    warn("$$ Apache::App::prepare_context(@_)\n");
+    my ($self, $app, $program) = @_;
+    if (!$context{$app} || !$options{$app}) {
+        $self->clear_context() if ($context{$app} || $options{$app});
+        my $prefix = $ENV{PREFIX} || $options{main}{prefix} || 
"/usr/local/app";
+        %App::options = (
+            app           => $app,
+            prefix        => $prefix,
+            context_class => "App::Context::ModPerl",
+        );
+        my $option_processor = App::Options->new({
+            init_args => {
+                no_cmd_args => 1,
+                no_env_vars => 1,
+                option => {
+                    session_class => { default => "App::Session::HTMLHidden", 
},
+                    request_class => { default => "App::Request::CGI", },
+                },
+            },
+        });
+        local($0) = $program;
+        $option_processor->read_options(\%App::options);
+        my $context = App->context();
+        $self->save_context($app);
+    }
+    elsif ($context{$app} ne $App::context) {
+        $self->restore_context($app);
+    }
+}
+
+######################################################################################
+# Upon child server startup (PerlChildInitHandler), services should be 
initialized
+# which may include repositories and hence possible connections to databases.
+######################################################################################
 
 sub init_service_on_child_init {
-    my (@args) = @_;
-    shift(@args);                    # get rid of class name
-    push(@service_on_init, [...@args]);
+    warn("$$ Apache::App::init_service_on_child_init(@_)\n");
+    my ($self, $app, @args) = @_;
+    push(@service_on_init, [$app, @args]);
+    warn("$$ Apache::App::init_service_on_child_init() : \$#service_on_init = 
[$#service_on_init]\n");
 }
 
 
######################################################################################
@@ -72,16 +226,21 @@
 
 sub child_init_handler {
     my ($child_pool, $s) = @_;
-    warn("$$ Apache::App child_init\n");
+    warn("$$ Apache::App::child_init_handler(@_) : \$#service_on_init = 
[$#service_on_init]\n");
 
-    #my $context = App->context();
-    #if (@service_on_init) {
-    #    for my $service_init_args (@service_on_init) {
-    #        $context->service(@$service_init_args);
-    #    }
-    #}
+    my ($app, $service);
+    if ($#service_on_init > -1) {
+        foreach my $service_init_args (@service_on_init) {
+            warn("$$ Apache::App::child_init_handler() : 
service_init_arg...@$service_init_args]\n");
+            $app = shift(@$service_init_args);
+            warn("$$ Apache::App::child_init_handler() : 
context($app).service(@$service_init_args)\n");
+            App::Apache->prepare_context($app);
+            $service = $App::context->service(@$service_init_args);
+            warn("$$ Apache::App::child_init_handler() : 
context($app).service(@$service_init_args) = [$service]\n");
+        }
+    }
 
-    return 1; # (MP2 ? Apache2::Const::OK : Apache::OK);
+    return 1;
 }
 
 
######################################################################################
@@ -90,8 +249,8 @@
 
 sub child_exit_handler {
     my ($child_pool, $s) = @_;
-    warn("$$ Apache::App child_exit\n");
-    return 1; # (MP2 ? Apache2::Const::OK : Apache::OK);
+    warn("$$ Apache::App::child_exit_handler(@_)\n");
+    return 1;
 }
 
 
######################################################################################
@@ -99,7 +258,7 @@
 
######################################################################################
 
 sub request_cleanup_handler {
-    warn("$$ Apache::App request_cleanup\n");
+    warn("$$ Apache::App::request_cleanup_handler(@_)\n");
 #    my $Idx = shift;
 #
 #    my $prefix = "$$ Apache::DBI            ";
@@ -123,134 +282,134 @@
 # Response Handler
 
######################################################################################
 
-sub handler {
-    my $r = shift;
-
-    if ($ENV{PATH_INFO} eq "/_info") {
-        &info($r);
-        return;
-    }
-
-    my ($msg, $response);
-
-    # INITIALIZE THE CONTEXT THE FIRST TIME THIS APACHE CHILD PROCESS
-    # RECEIVES A REQUEST (should I do this sooner? at child init?)
-    # (so that the first request does not need to bear the extra burden)
-
-    # Also, the App class would cache the $context for me
-    # if I didn't want to cache it myself. But then I would have to 
-    # prepare the %options every request. hmmm...
-    # I don't suppose the $r->dir_config() call is expensive.
-
-    if (!defined $context) {
-        my %options = %{$r->dir_config()};
-        $options{context_class} = "App::Context::ModPerl" if (!defined 
$options{context_class});
-        eval {
-            $context = App->context(\%options);
-        };
-        $msg = $@ if ($@);
-    }
-
-    if ($ENV{PATH_INFO} eq "/_context") {
-        my $header = <<EOF;
-Content-type: text/plain
-
-App::Context::ModPerl - Context
-
-EOF
-        $r->print($header);
-        $r->print($context->dump());
-        return;
-    }
-    elsif ($ENV{PATH_INFO} eq "/_session") {
-        my $header = <<EOF;
-Content-type: text/plain
-
-App::Context::ModPerl - Session
-
-EOF
-        $r->print($header);
-        $r->print($context->{session}->dump());
-        return;
-    }
-    elsif ($ENV{PATH_INFO} eq "/_conf") {
-        my $header = <<EOF;
-Content-type: text/plain
-
-App::Context::ModPerl - Conf
-
-EOF
-        $r->print($header);
-        $r->print($context->{conf}->dump());
-        return;
-    }
-    elsif ($ENV{PATH_INFO} eq "/_options") {
-        my $header = <<EOF;
-Content-type: text/plain
-
-App::Context::ModPerl - Options
-
-EOF
-        $r->print($header);
-        my $options = $context->{options} || {};
-        foreach my $key (sort keys %$options) {
-            $r->print("$key = $options->{$key}\n");
-        }
-        return;
-    }
-
-    # this should always be true
-    if (defined $context) {
-        # the response will be emitted from within dispatch_events()
-        $context->dispatch_events();
-    }
-    else {
-        # we had an error (maybe App-Context not installed? Perl @INC not set?)
-        $response = <<EOF;
-Content-type: text/plain
-
-Unable to create an App::Context.
-$msg
-
-EOF
-        $r->print($response);
-    }
-}
+#sub handler {
+#    my $r = shift;
+#
+#    if ($ENV{PATH_INFO} eq "/_info") {
+#        &info($r);
+#        return;
+#    }
+#
+#    my ($msg, $response);
+#
+#    # INITIALIZE THE CONTEXT THE FIRST TIME THIS APACHE CHILD PROCESS
+#    # RECEIVES A REQUEST (should I do this sooner? at child init?)
+#    # (so that the first request does not need to bear the extra burden)
+#
+#    # Also, the App class would cache the $context for me
+#    # if I didn't want to cache it myself. But then I would have to 
+#    # prepare the %options every request. hmmm...
+#    # I don't suppose the $r->dir_config() call is expensive.
+#
+#    if (!defined $context) {
+#        my %options = %{$r->dir_config()};
+#        $options{context_class} = "App::Context::ModPerl" if (!defined 
$options{context_class});
+#        eval {
+#            $context = App->context(\%options);
+#        };
+#        $msg = $@ if ($@);
+#    }
+#
+#    if ($ENV{PATH_INFO} eq "/_context") {
+#        my $header = <<EOF;
+#Content-type: text/plain
+#
+#App::Context::ModPerl - Context
+#
+#EOF
+#        $r->print($header);
+#        $r->print($context->dump());
+#        return;
+#    }
+#    elsif ($ENV{PATH_INFO} eq "/_session") {
+#        my $header = <<EOF;
+#Content-type: text/plain
+#
+#App::Context::ModPerl - Session
+#
+#EOF
+#        $r->print($header);
+#        $r->print($context->{session}->dump());
+#        return;
+#    }
+#    elsif ($ENV{PATH_INFO} eq "/_conf") {
+#        my $header = <<EOF;
+#Content-type: text/plain
+#
+#App::Context::ModPerl - Conf
+#
+#EOF
+#        $r->print($header);
+#        $r->print($context->{conf}->dump());
+#        return;
+#    }
+#    elsif ($ENV{PATH_INFO} eq "/_options") {
+#        my $header = <<EOF;
+#Content-type: text/plain
+#
+#App::Context::ModPerl - Options
+#
+#EOF
+#        $r->print($header);
+#        my $options = $context->{options} || {};
+#        foreach my $key (sort keys %$options) {
+#            $r->print("$key = $options->{$key}\n");
+#        }
+#        return;
+#    }
+#
+#    # this should always be true
+#    if (defined $context) {
+#        # the response will be emitted from within dispatch_events()
+#        $context->dispatch_events();
+#    }
+#    else {
+#        # we had an error (maybe App-Context not installed? Perl @INC not 
set?)
+#        $response = <<EOF;
+#Content-type: text/plain
+#
+#Unable to create an App::Context.
+#$msg
+#
+#EOF
+#        $r->print($response);
+#    }
+#}
 
 
######################################################################################
 # Special URL-driven Responses
 
######################################################################################
 
-sub info {
-    my $r = shift;
-    my $header = <<EOF;
-Content-type: text/plain
-
-Welcome to Apache::App
-
-EOF
-    $r->print($header);
-    print $r->as_string();
-    $r->print("\n");
-    $r->print("ENVIRONMENT VARIABLES\n");
-    $r->print("\n");
-    foreach my $var (sort keys %ENV) {
-        $r->print("$var=$ENV{$var}\n");
-    }
-    $r->print("\n");
-    $r->print("ENVIRONMENT VARIABLES (at startup)\n");
-    $r->print("\n");
-    foreach my $var (sort keys %env) {
-        $r->print("$var=$env{$var}\n");
-    }
-    $r->print("\n");
-    $r->print("DIRECTORY CONFIG\n");
-    $r->print("\n");
-    my %options = %{$r->dir_config()};
-    foreach my $var (sort keys %options) {
-        $r->print("$var=$options{$var}\n");
-    }
-}
+#sub info {
+#    my $r = shift;
+#    my $header = <<EOF;
+#Content-type: text/plain
+#
+#Welcome to Apache::App
+#
+#EOF
+#    $r->print($header);
+#    print $r->as_string();
+#    $r->print("\n");
+#    $r->print("ENVIRONMENT VARIABLES\n");
+#    $r->print("\n");
+#    foreach my $var (sort keys %ENV) {
+#        $r->print("$var=$ENV{$var}\n");
+#    }
+#    $r->print("\n");
+#    $r->print("ENVIRONMENT VARIABLES (at startup)\n");
+#    $r->print("\n");
+#    foreach my $var (sort keys %env) {
+#        $r->print("$var=$env{$var}\n");
+#    }
+#    $r->print("\n");
+#    $r->print("DIRECTORY CONFIG\n");
+#    $r->print("\n");
+#    my %options = %{$r->dir_config()};
+#    foreach my $var (sort keys %options) {
+#        $r->print("$var=$options{$var}\n");
+#    }
+#}
 
 # prepare menu item for Apache::Status
 #sub status_function {

Modified: p5ee/trunk/App-Context/lib/App.pm
==============================================================================
--- p5ee/trunk/App-Context/lib/App.pm   (original)
+++ p5ee/trunk/App-Context/lib/App.pm   Mon Aug 30 14:40:44 2010
@@ -633,8 +633,8 @@
 
 =cut
 
-my (%context);  # usually a singleton per process (under "default" name)
-                # multiple named contexts are allowed for debugging purposes
+our (%options);  # the default global location for conf options (%App::options)
+our ($context);  # a singleton per process (for exception see Apache::App)
 
 sub context {
     &App::sub_entry if ($App::trace);
@@ -660,7 +660,7 @@
         $name = "default" if (!$name);                # use "default" as name
     }
 
-    if (!defined $context{$name}) {
+    if (!defined $context) {
     
         if (! $options->{context_class}) {
             if (defined $ENV{APP_CONTEXT_CLASS}) {        # env variable set?
@@ -685,19 +685,20 @@
         }
 
         # instantiate Context and cache it (it's reference) for future use
-        $context{$name} = $self->new($options->{context_class}, "new", 
$options);
+        $context = $self->new($options->{context_class}, "new", $options);
     }
 
-    &App::sub_exit($context{$name}) if ($App::trace);
-    return($context{$name});
+    &App::sub_exit($context) if ($App::trace);
+    return($context);
 }
 
 sub shutdown {
     &App::sub_entry if ($App::trace);
-    my ($self, $name) = @_;
-    $name = "default" if (!defined $name);
-    $context{$name}->shutdown() if (defined $context{$name});
-    delete $context{$name};
+    my ($self) = @_;
+    if ($context) {
+        $context->shutdown();
+        $context = undef;
+    }
     &App::sub_exit() if ($App::trace);
 }
 

Reply via email to