Apache2-ASP

 view release on metacpan or  search on metacpan

lib/Apache2/ASP/ASPPage.pm  view on Meta::CPAN


package Apache2::ASP::ASPPage;

use strict;
use warnings 'all';
use Carp 'confess';
use base 'Apache2::ASP::HTTPHandler';
use vars __PACKAGE__->VARS;
use Apache2::ASP::ASPDOM::Node;
use Apache2::ASP::ASPDOM::Document;
use HTTP::Date 'time2iso';
use Scalar::Util 'weaken';

use Data::Dumper;


#==============================================================================
sub new
{
  my ($class, %args) = @_;
  
  $class->init_asp_objects( $class->context );
    
  foreach(qw/ virtual_path /)
  {
    confess "Required param '$_' was not provided"
      unless defined($args{$_});
  }# end foreach()
  
  # Just so we don't end up with an injection of some kind one day:
  delete($args{file_contents});
  
  my $s = bless \%args, $class;
  
  $s->{physical_path} = $s->context->server->MapPath( $s->virtual_path );
  confess "File not found: '@{[ $s->physical_path ]}'"
    unless -f $s->physical_path;
  
  my $pm_folder = $s->context->config->web->page_cache_root . '/' . $s->context->config->web->application_name;
  
  # Build out the folder structure to the Page Cache:
  my @parts = grep { length($_) } split /\//, $pm_folder;
  my $dir = '';
  foreach( @parts )
  {
    $dir .= "/$_";
    mkdir($dir) unless -d $dir;
  }# end foreach()
  
  my $pkg = $s->virtual_path;
  $pkg =~ s/^\///;
  $pkg =~ s/[^a-z0-9_]/_/ig;
  $s->{package_name} = $s->context->config->web->application_name . '::' . $pkg;
  $s->{pm_path} = $pm_folder . '/' . $pkg . '.pm';
  my $pm_inc = $s->context->config->web->application_name . '/' . $pkg . '.pm';
  
  # Determine age of ASP and PM:
  my $asp_age = (stat($s->context->server->MapPath($s->virtual_path)))[9];
  no strict 'refs';
  my $timestamp = ${$s->package_name . "::TIMESTAMP"} || 0;
  my $pm_age  = (stat($s->pm_path))[9] || 0;

  if( ( ! $pm_age ) || ( $asp_age > $pm_age ) )
  {
#warn "(Re)compiling $pkg";
    delete( $INC{$pm_inc} );
    $s->_init_source_code();
    $s->parse;
    require $pm_inc;
  }
  elsif( $asp_age > $timestamp )
  {
#warn "(Re)loading $pkg";
    delete( $INC{$pm_inc} );
    require $pm_inc;
  }# end if()
  
  return $s;
}# end new()


#==============================================================================
# Public read-only properties:
sub physical_path { $_[0]->{physical_path} }
sub virtual_path  { $_[0]->{virtual_path}  }
sub context       { $Apache2::ASP::HTTPContext::ClassName->current }
sub package_name  { $_[0]->{package_name} }
sub pm_path       { $_[0]->{pm_path}     }
sub directives    { my $s = shift; @_ ? $s->{directives} = shift : $s->{directives} || { } }
sub source_code   { $_[0]->{source_code} }
sub file_contents { $_[0]->{file_contents} }
sub is_masterpage { $_[0]->{is_masterpage} || 0 > 0 }
sub masterpage    { $_[0]->{masterpage} or return; $_[0]->{masterpage} }
sub placeholders  { my $s = shift; @_ ? $s->{placeholders} = shift : $s->{placeholders} || { } }
sub placeholder_contents { $_[0]->{placeholder_contents} || { } }


#==============================================================================
# Public read-write properties:
sub childpage
{
  my $s = shift;
  
  @_ ? $s->{childpage} = shift : $s->{childpage};
}# end childpage()


#==============================================================================
sub _init_source_code
{
  my ($s) = @_;
  
  return $s->{file_contents} if defined($s->{file_contents});
  
  open my $ifh, '<', $s->physical_path
    or confess "Cannot open '@{[ $s->physical_path ]}' for reading: $!";
  local $/;
  my $data = <$ifh>;
  $s->{source_code} = \"$data";
  $s->{file_contents} = \$data;
}# end _init_source_code()



( run in 1.733 second using v1.01-cache-2.11-cpan-39bf76dae61 )