You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axkit-dev@xml.apache.org by ma...@apache.org on 2003/10/20 22:58:02 UTC

cvs commit: xml-axkit/t/xslt-basic 02_include.t

mach        2003/10/20 13:58:02

  Modified:    .        Tag: axkit-pipeline-2 MANIFEST
               lib/Apache/AxKit Tag: axkit-pipeline-2 Cache.pm
               lib/Apache/AxKit/Language Tag: axkit-pipeline-2 HtmlDoc.pm
                        LibXSLT.pm XSP.pm
               t/conf   Tag: axkit-pipeline-2 extra.last.conf.in
               t/xslt-basic Tag: axkit-pipeline-2 02_include.t
  Added:       lib/Apache/AxKit Tag: axkit-pipeline-2 Pipeline.pm
               lib/Apache/AxKit/Pipeline Tag: axkit-pipeline-2 Cache.pm
                        Head.pm Language.pm LibXSLT.pm Trace.pm
                        Transformer.pm XSP.pm
               t/htdocs/pipeline/cache Tag: axkit-pipeline-2 01.xml
               t/htdocs/style/pipeline/cache Tag: axkit-pipeline-2 01.xsl
               t/pipeline Tag: axkit-pipeline-2 01cache.t
  Log:
  Big commit of new pipeline code. Lots of new shiny pipeline modules.
  Minor changes to some Language::* modules (will be ported eventually),
  changes to Cache.pm adding dependancy checking. Test and Enjoy.
  
  Revision  Changes    Path
  No                   revision
  No                   revision
  1.20.2.1  +10 -1     xml-axkit/MANIFEST
  
  Index: MANIFEST
  ===================================================================
  RCS file: /home/cvs/xml-axkit/MANIFEST,v
  retrieving revision 1.20
  retrieving revision 1.20.2.1
  diff -u -r1.20 -r1.20.2.1
  --- MANIFEST	19 Oct 2003 16:09:36 -0000	1.20
  +++ MANIFEST	20 Oct 2003 20:58:01 -0000	1.20.2.1
  @@ -157,6 +157,12 @@
   lib/Apache/AxKit/Provider/FileWrite.pm
   lib/Apache/AxKit/Provider/Filter.pm
   lib/Apache/AxKit/Provider/Scalar.pm
  +lib/Apache/AxKit/Pipeline.pm
  +lib/Apache/AxKit/Pipeline/Trace.pm
  +lib/Apache/AxKit/Pipeline/XSP.pm
  +lib/Apache/AxKit/Pipeline/LibXSLT.pm
  +lib/Apache/AxKit/Pipeline/Cache.pm
  +lib/Apache/AxKit/Pipeline/Language.pm
   lib/Apache/AxKit/StyleChooser/Cookie.pm
   lib/Apache/AxKit/StyleChooser/FileSuffix.pm
   lib/Apache/AxKit/StyleChooser/PathInfo.pm
  @@ -208,5 +214,8 @@
   t/htdocs/uri/axkit/subrequest.xml
   t/htdocs/style/uri/axkit/01.xsl
   t/htdocs/style/uri/axkit/subrequest.xsl
  -
  +t/htdocs/pipeline/cache/01.xml
  +t/htdocs/style/pipeline/cache
  +t/htdocs/style/pipeline/cache/01.xsl
  +t/pipeline/01cache.t
   typemap
  
  
  
  No                   revision
  No                   revision
  1.12.2.1  +120 -51   xml-axkit/lib/Apache/AxKit/Cache.pm
  
  Index: Cache.pm
  ===================================================================
  RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/Cache.pm,v
  retrieving revision 1.12
  retrieving revision 1.12.2.1
  diff -u -r1.12 -r1.12.2.1
  --- Cache.pm	3 Oct 2003 18:38:38 -0000	1.12
  +++ Cache.pm	20 Oct 2003 20:58:01 -0000	1.12.2.1
  @@ -1,5 +1,3 @@
  -# $Id$
  -
   package Apache::AxKit::Cache;
   use strict;
   
  @@ -72,14 +70,15 @@
      }
   
       my $self = bless { 
  -        apache => $r,
  -        key => $key, 
  -        no_cache => $no_cache, 
  -        dir => $cachedir,
  -        file => "$cachedir/$primary/$secondary/$key",
  -        gzip => $gzip,
  +        apache 		=> $r,
  +        key 		=> $key, 
  +        no_cache 	=> $no_cache, 
  +        dir 		=> $cachedir,
  +        file 		=> "$cachedir/$primary/$secondary/$key",
  +        gzip 		=> $gzip,
  +        depends 	=> {},
   #        extras => \@extras,
  -        }, $class;
  +   	}, $class;
   
       if (my $alternate = $AxKit::Cfg->CacheModule()) {
           AxKit::reconsecrate($self, $alternate);
  @@ -108,8 +107,10 @@
   
   sub write {
       my $self = shift;
  +    my ($content, $encoding) = @_;
  +    $content = ref($content) ? $$content : $content;
       return if $self->{no_cache};
  -    my $encoding = $_[1] || 'raw';
  +    $encoding ||= 'raw';
       AxKit::Debug(7, "[Cache] writing cache file $self->{file}");
       my $fh = Apache->gensym();
       my $tmp_filename = $self->{file}."new$$";
  @@ -117,7 +118,7 @@
           # flock($fh, LOCK_EX);
           # seek($fh, 0, 0);
           # truncate($fh, 0);
  -        print $fh $_[0];
  +        print $fh $content;
           close $fh;
           rename($tmp_filename, $self->{file}) 
                   || throw Apache::AxKit::Exception::IO( -text => "Couldn't rename cachefile: $!");
  @@ -125,11 +126,21 @@
       else {
           throw Apache::AxKit::Exception::IO( -text => "Couldn't open cachefile for writing: $!");
       }
  +
  +    if (AxKit::sysopen($fh, $tmp_filename, O_WRONLY|O_CREAT, 'raw')) {
  +        print $fh join("\n", keys %{$self->{'depends'}});
  +        close $fh;
  +        rename($tmp_filename, $self->{file}.'.depends') 
  +                || throw Apache::AxKit::Exception::IO( -text => "Couldn't rename cachefile: $!");
  +    }
  +    else {
  +        throw Apache::AxKit::Exception::IO( -text => "Couldn't open cachefile for writing: $!");
  +    }
       
       if ($self->{gzip} && $AxKit::Cfg->GzipOutput) {
           AxKit::Debug(3, "Creating gzip output cache: $self->{file}.gz");
           if (my $gz = gzopen($self->{file}.'new.gz', "wb")) {
  -            $gz->gzwrite($_[0]);
  +            $gz->gzwrite($content);
               $gz->gzclose();
               rename($self->{file}.'new.gz', $self->{file}.'.gz')
                       || throw Apache::AxKit::Exception::IO( -text => "Couldn't rename gzipped cachefile: $!");
  @@ -141,22 +152,25 @@
   }
   
   sub read {
  -    my $self = shift;
  -    return if $self->{no_cache};
  +    my ($self)  = @_;
       my $encoding = $_[0] || 'raw';
  -    my $fh = Apache->gensym();
  -    if (AxKit::sysopen($fh, $self->{file}, O_RDONLY, $encoding)) {
  -        flock($fh, LOCK_SH);
  -        local $/;
  -        return <$fh>;
  -        # close($fh);
  -        # close unlocks automatically
  +    return if $self->{no_cache};
  +    if($self->check_dependencies()) {
  +        my $fh = Apache->gensym();
  +    	if (AxKit::sysopen($fh, $self->{file}, O_RDONLY, $encoding)) {
  +    	    flock($fh, LOCK_SH);
  +    	    local $/;
  +    	    return <$fh>;
  +    	    # close($fh);
  +    	    # close unlocks automatically
  +    	}
       }
  -    return '';
  +   	return undef;
   }
   
   sub get_fh {
       my $self = shift;
  +    warn("cache get_fh called");
       return if $self->{no_cache};
       my $fh = Apache->gensym();
       if (AxKit::sysopen($fh, $self->{file}, O_RDONLY, 'raw')) {
  @@ -203,7 +217,9 @@
   
   sub deliver {
       my $self = shift;
  -    return SERVER_ERROR if $self->{no_cache};
  +    Apache::AxKit::Exception::Error->throw(
  +    	-text => 'attempt to deliver from cache when no cache set'
  +    ) if $self->{no_cache};
       my $r = $self->{apache};
   
       {
  @@ -215,46 +231,99 @@
           }
       }
   
  -    if ($r->content_type eq 'changeme' && !$r->notes('axkit_passthru_type')) {
  -        $AxKit::Cfg->AllowOutputCharset(1);
  -        $r->content_type('text/html; charset=' . ($AxKit::Cfg->OutputCharset || "UTF-8"));
  -    }
  -    elsif ($r->notes('axkit_passthru_type')) {
  -        $r->content_type($AxKit::OrigType);
  -    }
  +#    if ($r->content_type eq 'changeme' && !$r->notes('axkit_passthru_type')) {
  +#        $AxKit::Cfg->AllowOutputCharset(1);
  +#        $r->content_type('text/html; charset=' . ($AxKit::Cfg->OutputCharset || "UTF-8"));
  +#    }
  +#    elsif ($r->notes('axkit_passthru_type')) {
  +#        $r->content_type($AxKit::OrigType);
  +#    }
   
   
       my ($transformer, $doit) = AxKit::get_output_transformer();
   
  -    if ($doit) {
  -        AxKit::Debug(4, "Cache: Transforming content and printing to browser");
  -        $r->pnotes('xml_string',$self->read());
  -        return OK; # upstream deliver_to_browser should handle the rest
  -    }
  -    else {
  -        AxKit::Debug(4, "Cache: Sending untransformed content to browser");
  +   	throw Apache::AxKit::Exception::Error->throw(
  +   		-text => "cache deliver called when cache can't fast deliver"
  +   	) if $doit;
  +
  +	AxKit::Debug(4, "Cache: Sending untransformed content to browser");
  +
  +	# Make sure we unset PATH_INFO or wierd things can happen!
  +	$ENV{PATH_INFO} = '';
  +	$r->path_info('');
  +
  +	if ($self->{gzip} && $AxKit::Cfg->DoGzip) {
  +		AxKit::Debug(4, 'Cache: Delivering gzipped output');
  +		$r->filename($self->{file}.'.gz');
  +	}
  +	else {
  +		$r->filename($self->{file});
  +	}
   
  -        # Make sure we unset PATH_INFO or wierd things can happen!
  -        $ENV{PATH_INFO} = '';
  -        $r->path_info('');
  -
  -        if ($self->{gzip} && $AxKit::Cfg->DoGzip) {
  -            AxKit::Debug(4, 'Cache: Delivering gzipped output');
  -            $r->filename($self->{file}.'.gz');
  -        }
  -        else {
  -            $r->filename($self->{file});
  -        }
  +	# Apache::AxKit::Exception::Declined->throw();	# handler will catch
  +}
  +
  +sub add_dependencies{
  +	my $self = shift;
  +	foreach my $d ( @_ ) {
  +		$self->{'depends'}->{$d}++;
  +	}
  +}
   
  -        return DECLINED;
  -    }
   
  +sub load_dependencies{
  +    my $self = shift;
  +    return if $self->{no_cache};
  +    my $fh = Apache->gensym();
  +    my @depends;
  +    if (AxKit::sysopen($fh, $self->{file}.'.depends', O_RDONLY,'raw')) {
  +        flock($fh, LOCK_SH);
  +        @depends = <$fh>;
  +        chomp(@depends);
  +        close($fh);
  +        # close unlocks automatically
  +    } else {
  +    	# there should always be a cache dependency file
  +    	# since an empty file is different to there not being a file
  +       	Apache::AxKit::Exception::Error->throw( -text => "no cache dependency file");
  +    }    
  +    return @depends;
  +}
  +
  +sub check_dependencies{
  +    my ($self) = @_;
  +    
  +    my $r =  $self->{'apache'};
  +    
  +	foreach my $dependency ( $self->load_dependencies() ) {	
  +		
  +		# nasty $self->apache here cause the number of places
  +		# I'd have to check/change for passing $r was too many
  +		# to bother with. Hopefully this will all get cleaned up.
  +		# well, it changes the interface to cache->read().
  +		
  +		$dependency =~ s|^\{(\w+)\}||;
  +		my $dep_type = $1;
  +		AxKit::Debug(3, "Checking dependency: $dependency of type $dep_type");
  +		my $dep = ($dep_type eq "style") ?
  +			Apache::AxKit::Provider->new_style_provider($r, key => $dependency) :
  +			Apache::AxKit::Provider->new($r, key => $dependency);		
  +
  +		if ( $dep->has_changed( $self->mtime() ) ) {
  +			AxKit::Debug(4, "dependency: $dependency newer");
  +			return 0;
  +		}
  +	}
  +    return 1;
   }
   
   sub reset {
       my $self = shift;
       unlink $self->{file};
  -}
  +    unlink $self->{file}.".depends";
  +    unlink $self->{file}.".gz";
  +    unlink $self->{file}.".type";
  + }
   
   sub mtime {
       my $self = shift;
  
  
  
  No                   revision
  
  Index: Cache.pm
  ===================================================================
  RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/Cache.pm,v
  retrieving revision 1.12
  retrieving revision 1.12.2.1
  diff -u -r1.12 -r1.12.2.1
  --- Cache.pm	3 Oct 2003 18:38:38 -0000	1.12
  +++ Cache.pm	20 Oct 2003 20:58:01 -0000	1.12.2.1
  @@ -1,5 +1,3 @@
  -# $Id$
  -
   package Apache::AxKit::Cache;
   use strict;
   
  @@ -72,14 +70,15 @@
      }
   
       my $self = bless { 
  -        apache => $r,
  -        key => $key, 
  -        no_cache => $no_cache, 
  -        dir => $cachedir,
  -        file => "$cachedir/$primary/$secondary/$key",
  -        gzip => $gzip,
  +        apache 		=> $r,
  +        key 		=> $key, 
  +        no_cache 	=> $no_cache, 
  +        dir 		=> $cachedir,
  +        file 		=> "$cachedir/$primary/$secondary/$key",
  +        gzip 		=> $gzip,
  +        depends 	=> {},
   #        extras => \@extras,
  -        }, $class;
  +   	}, $class;
   
       if (my $alternate = $AxKit::Cfg->CacheModule()) {
           AxKit::reconsecrate($self, $alternate);
  @@ -108,8 +107,10 @@
   
   sub write {
       my $self = shift;
  +    my ($content, $encoding) = @_;
  +    $content = ref($content) ? $$content : $content;
       return if $self->{no_cache};
  -    my $encoding = $_[1] || 'raw';
  +    $encoding ||= 'raw';
       AxKit::Debug(7, "[Cache] writing cache file $self->{file}");
       my $fh = Apache->gensym();
       my $tmp_filename = $self->{file}."new$$";
  @@ -117,7 +118,7 @@
           # flock($fh, LOCK_EX);
           # seek($fh, 0, 0);
           # truncate($fh, 0);
  -        print $fh $_[0];
  +        print $fh $content;
           close $fh;
           rename($tmp_filename, $self->{file}) 
                   || throw Apache::AxKit::Exception::IO( -text => "Couldn't rename cachefile: $!");
  @@ -125,11 +126,21 @@
       else {
           throw Apache::AxKit::Exception::IO( -text => "Couldn't open cachefile for writing: $!");
       }
  +
  +    if (AxKit::sysopen($fh, $tmp_filename, O_WRONLY|O_CREAT, 'raw')) {
  +        print $fh join("\n", keys %{$self->{'depends'}});
  +        close $fh;
  +        rename($tmp_filename, $self->{file}.'.depends') 
  +                || throw Apache::AxKit::Exception::IO( -text => "Couldn't rename cachefile: $!");
  +    }
  +    else {
  +        throw Apache::AxKit::Exception::IO( -text => "Couldn't open cachefile for writing: $!");
  +    }
       
       if ($self->{gzip} && $AxKit::Cfg->GzipOutput) {
           AxKit::Debug(3, "Creating gzip output cache: $self->{file}.gz");
           if (my $gz = gzopen($self->{file}.'new.gz', "wb")) {
  -            $gz->gzwrite($_[0]);
  +            $gz->gzwrite($content);
               $gz->gzclose();
               rename($self->{file}.'new.gz', $self->{file}.'.gz')
                       || throw Apache::AxKit::Exception::IO( -text => "Couldn't rename gzipped cachefile: $!");
  @@ -141,22 +152,25 @@
   }
   
   sub read {
  -    my $self = shift;
  -    return if $self->{no_cache};
  +    my ($self)  = @_;
       my $encoding = $_[0] || 'raw';
  -    my $fh = Apache->gensym();
  -    if (AxKit::sysopen($fh, $self->{file}, O_RDONLY, $encoding)) {
  -        flock($fh, LOCK_SH);
  -        local $/;
  -        return <$fh>;
  -        # close($fh);
  -        # close unlocks automatically
  +    return if $self->{no_cache};
  +    if($self->check_dependencies()) {
  +        my $fh = Apache->gensym();
  +    	if (AxKit::sysopen($fh, $self->{file}, O_RDONLY, $encoding)) {
  +    	    flock($fh, LOCK_SH);
  +    	    local $/;
  +    	    return <$fh>;
  +    	    # close($fh);
  +    	    # close unlocks automatically
  +    	}
       }
  -    return '';
  +   	return undef;
   }
   
   sub get_fh {
       my $self = shift;
  +    warn("cache get_fh called");
       return if $self->{no_cache};
       my $fh = Apache->gensym();
       if (AxKit::sysopen($fh, $self->{file}, O_RDONLY, 'raw')) {
  @@ -203,7 +217,9 @@
   
   sub deliver {
       my $self = shift;
  -    return SERVER_ERROR if $self->{no_cache};
  +    Apache::AxKit::Exception::Error->throw(
  +    	-text => 'attempt to deliver from cache when no cache set'
  +    ) if $self->{no_cache};
       my $r = $self->{apache};
   
       {
  @@ -215,46 +231,99 @@
           }
       }
   
  -    if ($r->content_type eq 'changeme' && !$r->notes('axkit_passthru_type')) {
  -        $AxKit::Cfg->AllowOutputCharset(1);
  -        $r->content_type('text/html; charset=' . ($AxKit::Cfg->OutputCharset || "UTF-8"));
  -    }
  -    elsif ($r->notes('axkit_passthru_type')) {
  -        $r->content_type($AxKit::OrigType);
  -    }
  +#    if ($r->content_type eq 'changeme' && !$r->notes('axkit_passthru_type')) {
  +#        $AxKit::Cfg->AllowOutputCharset(1);
  +#        $r->content_type('text/html; charset=' . ($AxKit::Cfg->OutputCharset || "UTF-8"));
  +#    }
  +#    elsif ($r->notes('axkit_passthru_type')) {
  +#        $r->content_type($AxKit::OrigType);
  +#    }
   
   
       my ($transformer, $doit) = AxKit::get_output_transformer();
   
  -    if ($doit) {
  -        AxKit::Debug(4, "Cache: Transforming content and printing to browser");
  -        $r->pnotes('xml_string',$self->read());
  -        return OK; # upstream deliver_to_browser should handle the rest
  -    }
  -    else {
  -        AxKit::Debug(4, "Cache: Sending untransformed content to browser");
  +   	throw Apache::AxKit::Exception::Error->throw(
  +   		-text => "cache deliver called when cache can't fast deliver"
  +   	) if $doit;
  +
  +	AxKit::Debug(4, "Cache: Sending untransformed content to browser");
  +
  +	# Make sure we unset PATH_INFO or wierd things can happen!
  +	$ENV{PATH_INFO} = '';
  +	$r->path_info('');
  +
  +	if ($self->{gzip} && $AxKit::Cfg->DoGzip) {
  +		AxKit::Debug(4, 'Cache: Delivering gzipped output');
  +		$r->filename($self->{file}.'.gz');
  +	}
  +	else {
  +		$r->filename($self->{file});
  +	}
   
  -        # Make sure we unset PATH_INFO or wierd things can happen!
  -        $ENV{PATH_INFO} = '';
  -        $r->path_info('');
  -
  -        if ($self->{gzip} && $AxKit::Cfg->DoGzip) {
  -            AxKit::Debug(4, 'Cache: Delivering gzipped output');
  -            $r->filename($self->{file}.'.gz');
  -        }
  -        else {
  -            $r->filename($self->{file});
  -        }
  +	# Apache::AxKit::Exception::Declined->throw();	# handler will catch
  +}
  +
  +sub add_dependencies{
  +	my $self = shift;
  +	foreach my $d ( @_ ) {
  +		$self->{'depends'}->{$d}++;
  +	}
  +}
   
  -        return DECLINED;
  -    }
   
  +sub load_dependencies{
  +    my $self = shift;
  +    return if $self->{no_cache};
  +    my $fh = Apache->gensym();
  +    my @depends;
  +    if (AxKit::sysopen($fh, $self->{file}.'.depends', O_RDONLY,'raw')) {
  +        flock($fh, LOCK_SH);
  +        @depends = <$fh>;
  +        chomp(@depends);
  +        close($fh);
  +        # close unlocks automatically
  +    } else {
  +    	# there should always be a cache dependency file
  +    	# since an empty file is different to there not being a file
  +       	Apache::AxKit::Exception::Error->throw( -text => "no cache dependency file");
  +    }    
  +    return @depends;
  +}
  +
  +sub check_dependencies{
  +    my ($self) = @_;
  +    
  +    my $r =  $self->{'apache'};
  +    
  +	foreach my $dependency ( $self->load_dependencies() ) {	
  +		
  +		# nasty $self->apache here cause the number of places
  +		# I'd have to check/change for passing $r was too many
  +		# to bother with. Hopefully this will all get cleaned up.
  +		# well, it changes the interface to cache->read().
  +		
  +		$dependency =~ s|^\{(\w+)\}||;
  +		my $dep_type = $1;
  +		AxKit::Debug(3, "Checking dependency: $dependency of type $dep_type");
  +		my $dep = ($dep_type eq "style") ?
  +			Apache::AxKit::Provider->new_style_provider($r, key => $dependency) :
  +			Apache::AxKit::Provider->new($r, key => $dependency);		
  +
  +		if ( $dep->has_changed( $self->mtime() ) ) {
  +			AxKit::Debug(4, "dependency: $dependency newer");
  +			return 0;
  +		}
  +	}
  +    return 1;
   }
   
   sub reset {
       my $self = shift;
       unlink $self->{file};
  -}
  +    unlink $self->{file}.".depends";
  +    unlink $self->{file}.".gz";
  +    unlink $self->{file}.".type";
  + }
   
   sub mtime {
       my $self = shift;
  
  
  
  No                   revision
  
  Index: Cache.pm
  ===================================================================
  RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/Cache.pm,v
  retrieving revision 1.12
  retrieving revision 1.12.2.1
  diff -u -r1.12 -r1.12.2.1
  --- Cache.pm	3 Oct 2003 18:38:38 -0000	1.12
  +++ Cache.pm	20 Oct 2003 20:58:01 -0000	1.12.2.1
  @@ -1,5 +1,3 @@
  -# $Id$
  -
   package Apache::AxKit::Cache;
   use strict;
   
  @@ -72,14 +70,15 @@
      }
   
       my $self = bless { 
  -        apache => $r,
  -        key => $key, 
  -        no_cache => $no_cache, 
  -        dir => $cachedir,
  -        file => "$cachedir/$primary/$secondary/$key",
  -        gzip => $gzip,
  +        apache 		=> $r,
  +        key 		=> $key, 
  +        no_cache 	=> $no_cache, 
  +        dir 		=> $cachedir,
  +        file 		=> "$cachedir/$primary/$secondary/$key",
  +        gzip 		=> $gzip,
  +        depends 	=> {},
   #        extras => \@extras,
  -        }, $class;
  +   	}, $class;
   
       if (my $alternate = $AxKit::Cfg->CacheModule()) {
           AxKit::reconsecrate($self, $alternate);
  @@ -108,8 +107,10 @@
   
   sub write {
       my $self = shift;
  +    my ($content, $encoding) = @_;
  +    $content = ref($content) ? $$content : $content;
       return if $self->{no_cache};
  -    my $encoding = $_[1] || 'raw';
  +    $encoding ||= 'raw';
       AxKit::Debug(7, "[Cache] writing cache file $self->{file}");
       my $fh = Apache->gensym();
       my $tmp_filename = $self->{file}."new$$";
  @@ -117,7 +118,7 @@
           # flock($fh, LOCK_EX);
           # seek($fh, 0, 0);
           # truncate($fh, 0);
  -        print $fh $_[0];
  +        print $fh $content;
           close $fh;
           rename($tmp_filename, $self->{file}) 
                   || throw Apache::AxKit::Exception::IO( -text => "Couldn't rename cachefile: $!");
  @@ -125,11 +126,21 @@
       else {
           throw Apache::AxKit::Exception::IO( -text => "Couldn't open cachefile for writing: $!");
       }
  +
  +    if (AxKit::sysopen($fh, $tmp_filename, O_WRONLY|O_CREAT, 'raw')) {
  +        print $fh join("\n", keys %{$self->{'depends'}});
  +        close $fh;
  +        rename($tmp_filename, $self->{file}.'.depends') 
  +                || throw Apache::AxKit::Exception::IO( -text => "Couldn't rename cachefile: $!");
  +    }
  +    else {
  +        throw Apache::AxKit::Exception::IO( -text => "Couldn't open cachefile for writing: $!");
  +    }
       
       if ($self->{gzip} && $AxKit::Cfg->GzipOutput) {
           AxKit::Debug(3, "Creating gzip output cache: $self->{file}.gz");
           if (my $gz = gzopen($self->{file}.'new.gz', "wb")) {
  -            $gz->gzwrite($_[0]);
  +            $gz->gzwrite($content);
               $gz->gzclose();
               rename($self->{file}.'new.gz', $self->{file}.'.gz')
                       || throw Apache::AxKit::Exception::IO( -text => "Couldn't rename gzipped cachefile: $!");
  @@ -141,22 +152,25 @@
   }
   
   sub read {
  -    my $self = shift;
  -    return if $self->{no_cache};
  +    my ($self)  = @_;
       my $encoding = $_[0] || 'raw';
  -    my $fh = Apache->gensym();
  -    if (AxKit::sysopen($fh, $self->{file}, O_RDONLY, $encoding)) {
  -        flock($fh, LOCK_SH);
  -        local $/;
  -        return <$fh>;
  -        # close($fh);
  -        # close unlocks automatically
  +    return if $self->{no_cache};
  +    if($self->check_dependencies()) {
  +        my $fh = Apache->gensym();
  +    	if (AxKit::sysopen($fh, $self->{file}, O_RDONLY, $encoding)) {
  +    	    flock($fh, LOCK_SH);
  +    	    local $/;
  +    	    return <$fh>;
  +    	    # close($fh);
  +    	    # close unlocks automatically
  +    	}
       }
  -    return '';
  +   	return undef;
   }
   
   sub get_fh {
       my $self = shift;
  +    warn("cache get_fh called");
       return if $self->{no_cache};
       my $fh = Apache->gensym();
       if (AxKit::sysopen($fh, $self->{file}, O_RDONLY, 'raw')) {
  @@ -203,7 +217,9 @@
   
   sub deliver {
       my $self = shift;
  -    return SERVER_ERROR if $self->{no_cache};
  +    Apache::AxKit::Exception::Error->throw(
  +    	-text => 'attempt to deliver from cache when no cache set'
  +    ) if $self->{no_cache};
       my $r = $self->{apache};
   
       {
  @@ -215,46 +231,99 @@
           }
       }
   
  -    if ($r->content_type eq 'changeme' && !$r->notes('axkit_passthru_type')) {
  -        $AxKit::Cfg->AllowOutputCharset(1);
  -        $r->content_type('text/html; charset=' . ($AxKit::Cfg->OutputCharset || "UTF-8"));
  -    }
  -    elsif ($r->notes('axkit_passthru_type')) {
  -        $r->content_type($AxKit::OrigType);
  -    }
  +#    if ($r->content_type eq 'changeme' && !$r->notes('axkit_passthru_type')) {
  +#        $AxKit::Cfg->AllowOutputCharset(1);
  +#        $r->content_type('text/html; charset=' . ($AxKit::Cfg->OutputCharset || "UTF-8"));
  +#    }
  +#    elsif ($r->notes('axkit_passthru_type')) {
  +#        $r->content_type($AxKit::OrigType);
  +#    }
   
   
       my ($transformer, $doit) = AxKit::get_output_transformer();
   
  -    if ($doit) {
  -        AxKit::Debug(4, "Cache: Transforming content and printing to browser");
  -        $r->pnotes('xml_string',$self->read());
  -        return OK; # upstream deliver_to_browser should handle the rest
  -    }
  -    else {
  -        AxKit::Debug(4, "Cache: Sending untransformed content to browser");
  +   	throw Apache::AxKit::Exception::Error->throw(
  +   		-text => "cache deliver called when cache can't fast deliver"
  +   	) if $doit;
  +
  +	AxKit::Debug(4, "Cache: Sending untransformed content to browser");
  +
  +	# Make sure we unset PATH_INFO or wierd things can happen!
  +	$ENV{PATH_INFO} = '';
  +	$r->path_info('');
  +
  +	if ($self->{gzip} && $AxKit::Cfg->DoGzip) {
  +		AxKit::Debug(4, 'Cache: Delivering gzipped output');
  +		$r->filename($self->{file}.'.gz');
  +	}
  +	else {
  +		$r->filename($self->{file});
  +	}
   
  -        # Make sure we unset PATH_INFO or wierd things can happen!
  -        $ENV{PATH_INFO} = '';
  -        $r->path_info('');
  -
  -        if ($self->{gzip} && $AxKit::Cfg->DoGzip) {
  -            AxKit::Debug(4, 'Cache: Delivering gzipped output');
  -            $r->filename($self->{file}.'.gz');
  -        }
  -        else {
  -            $r->filename($self->{file});
  -        }
  +	# Apache::AxKit::Exception::Declined->throw();	# handler will catch
  +}
  +
  +sub add_dependencies{
  +	my $self = shift;
  +	foreach my $d ( @_ ) {
  +		$self->{'depends'}->{$d}++;
  +	}
  +}
   
  -        return DECLINED;
  -    }
   
  +sub load_dependencies{
  +    my $self = shift;
  +    return if $self->{no_cache};
  +    my $fh = Apache->gensym();
  +    my @depends;
  +    if (AxKit::sysopen($fh, $self->{file}.'.depends', O_RDONLY,'raw')) {
  +        flock($fh, LOCK_SH);
  +        @depends = <$fh>;
  +        chomp(@depends);
  +        close($fh);
  +        # close unlocks automatically
  +    } else {
  +    	# there should always be a cache dependency file
  +    	# since an empty file is different to there not being a file
  +       	Apache::AxKit::Exception::Error->throw( -text => "no cache dependency file");
  +    }    
  +    return @depends;
  +}
  +
  +sub check_dependencies{
  +    my ($self) = @_;
  +    
  +    my $r =  $self->{'apache'};
  +    
  +	foreach my $dependency ( $self->load_dependencies() ) {	
  +		
  +		# nasty $self->apache here cause the number of places
  +		# I'd have to check/change for passing $r was too many
  +		# to bother with. Hopefully this will all get cleaned up.
  +		# well, it changes the interface to cache->read().
  +		
  +		$dependency =~ s|^\{(\w+)\}||;
  +		my $dep_type = $1;
  +		AxKit::Debug(3, "Checking dependency: $dependency of type $dep_type");
  +		my $dep = ($dep_type eq "style") ?
  +			Apache::AxKit::Provider->new_style_provider($r, key => $dependency) :
  +			Apache::AxKit::Provider->new($r, key => $dependency);		
  +
  +		if ( $dep->has_changed( $self->mtime() ) ) {
  +			AxKit::Debug(4, "dependency: $dependency newer");
  +			return 0;
  +		}
  +	}
  +    return 1;
   }
   
   sub reset {
       my $self = shift;
       unlink $self->{file};
  -}
  +    unlink $self->{file}.".depends";
  +    unlink $self->{file}.".gz";
  +    unlink $self->{file}.".type";
  + }
   
   sub mtime {
       my $self = shift;
  
  
  
  1.1.2.1   +279 -0    xml-axkit/lib/Apache/AxKit/Attic/Pipeline.pm
  
  
  
  
  No                   revision
  No                   revision
  1.5.2.1   +46 -13    xml-axkit/lib/Apache/AxKit/Language/HtmlDoc.pm
  
  Index: HtmlDoc.pm
  ===================================================================
  RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/Language/HtmlDoc.pm,v
  retrieving revision 1.5
  retrieving revision 1.5.2.1
  diff -u -r1.5 -r1.5.2.1
  --- HtmlDoc.pm	28 Jul 2003 22:53:20 -0000	1.5
  +++ HtmlDoc.pm	20 Oct 2003 20:58:01 -0000	1.5.2.1
  @@ -12,6 +12,8 @@
   use Apache::AxKit::Language;
   use Apache::AxKit::LibXMLSupport;
   use Apache::AxKit::Provider;
  +use Apache::URI;
  +use URI;
   use XML::LibXSLT;
   use IPC::Run qw(run);
   use Cwd;
  @@ -21,6 +23,8 @@
   
   sub stylesheet_exists () { 0; }
   
  +
  +
   sub handler {
       my $class = shift;
       my ($r, $xml_provider, undef, $last_in_chain) = @_;
  @@ -46,12 +50,48 @@
           $dom = $parser->parse_string($source_text, $r->uri());
       }
       $dom->process_xinclude();
  +
  +	XML::LibXSLT->register_function("perl://apache/axkit/language/htmldoc", "url_fix",
  +		sub { 	my ($ref) = @_;
  +				my $str = $ref;
  +				eval {
  +					my $r = Apache->request();
  +					my $realabs = Apache::URI->parse($r)->unparse();
  +					$str = URI->new_abs( $ref, $realabs );
  +				};
  +				return "$str";
  +			}
  +	);
  +
       my $style_dom = $parser->parse_string(<< 'EOX','.');
   <?xml version="1.0"?>
  -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
  -<xsl:output method="html" encoding="ISO-8859-15"/>
  -<xsl:template match="*"><xsl:copy select="."><xsl:copy-of select="@*"/><xsl:apply-templates/></xsl:copy></xsl:template>
  -<xsl:template match="text()"><xsl:value-of select="."/></xsl:template>
  +<xsl:stylesheet version="1.0"
  +	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  +	xmlns:x="http://www.w3.org/1999/xhtml"
  +	xmlns:perl="perl://apache/axkit/language/htmldoc">
  +	<xsl:output method="html" encoding="ISO-8859-15"/>
  +	<xsl:template match="*">
  +		<!-- output mode="html" does not react nicely to namespaced elements -->
  +		<xsl:element name="{name()}">
  +				<xsl:apply-templates select="@*"/>
  +				<xsl:apply-templates/>
  +		</xsl:element>
  +	</xsl:template>
  +	<xsl:template match="@*">
  +			<xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
  +	</xsl:template>
  +	<xsl:template match="comment()">
  +		<!-- htmldoc uses comments as processing instructions -->
  +		<xsl:copy>
  +			<xsl:apply-templates/>
  +		</xsl:copy>
  +	</xsl:template>
  +	<xsl:template match="text()">
  +			<xsl:value-of select="."/>
  +	</xsl:template>
  +	<xsl:template match="@href|@x:href">
  +			<xsl:attribute name="href"><xsl:value-of select="perl:url_fix(.)"/></xsl:attribute>
  +	</xsl:template>
   </xsl:stylesheet>
   EOX
       my $stylesheet = XML::LibXSLT->parse_stylesheet($style_dom);
  @@ -59,16 +99,9 @@
   
       my $result;
       my $input = $stylesheet->output_string($results);
  -    my $host = $r->hostname;
  -    $input =~ s{ href="/}{ href="http://$host/}g;
  -    my $path = $r->document_root;
  -    $input =~ s{ src="/}{ src="$path/}g;
  -    $path = $r->uri;
  -    $path =~ s{/+[^/]*$}{/};
  -    $input =~ s{ href="(?!/|.{0,5}:)}{ href="http://$host$path}g;
       AxKit::Debug(8, "About to shell out to htmldoc - hope you have it installed...");
       AxKit::Debug(10, $input);
  -    run(['htmldoc','--quiet','--format','pdf13','--truetype','--size','a4','--color','--charset','8859-15','--webpage',$r->dir_config->get('AxHtmlDocOptions'),'-'],\$input,\$result);
  +    run(['htmldoc','--quiet','--format','pdf13','--embedfonts','--size','a4','--color','--charset','8859-15','--webpage',$r->dir_config->get('AxHtmlDocOptions'),'-'],\$input,\$result);
   
       if (substr($result,0,5) ne '%PDF-') {
           throw Apache::AxKit::Exception::Error(-text => 'htmldoc returned error: '.$result);
  
  
  
  1.22.2.1  +3 -1      xml-axkit/lib/Apache/AxKit/Language/LibXSLT.pm
  
  Index: LibXSLT.pm
  ===================================================================
  RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/Language/LibXSLT.pm,v
  retrieving revision 1.22
  retrieving revision 1.22.2.1
  diff -u -r1.22 -r1.22.2.1
  --- LibXSLT.pm	31 Jul 2003 16:48:15 -0000	1.22
  +++ LibXSLT.pm	20 Oct 2003 20:58:01 -0000	1.22.2.1
  @@ -45,6 +45,7 @@
       }
       else {
           $xmlstring = $r->pnotes('xml_string');
  +        delete $r->pnotes()->{'xml_string'};
       }
       
       my $parser = XML::LibXML->new();
  @@ -136,6 +137,7 @@
   
       AxKit::Debug(7, "[LibXSLT] storing results in pnotes(dom_tree) ($r)");
       $r->pnotes('dom_tree', $results);
  +    delete $r->pnotes()->{'xml_string'};
       
   #         warn "LibXSLT returned $output \n";
   #         print $stylesheet->output_string($results);
  
  
  
  1.51.2.1  +29 -3     xml-axkit/lib/Apache/AxKit/Language/XSP.pm
  
  Index: XSP.pm
  ===================================================================
  RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/Language/XSP.pm,v
  retrieving revision 1.51
  retrieving revision 1.51.2.1
  diff -u -r1.51 -r1.51.2.1
  --- XSP.pm	3 Oct 2003 18:38:38 -0000	1.51
  +++ XSP.pm	20 Oct 2003 20:58:01 -0000	1.51.2.1
  @@ -42,6 +42,28 @@
   #     return $parser->parsefile($filename);
   # }
   
  +sub compile{
  +	my ($class, $r, $key, $package, $to_parse) = @_;
  +	
  +    _register_me_and_others();
  +
  +#    warn "XSP Parse: $xmlfile\n";
  +
  +    my $handler = AxKit::XSP::SAXHandler->new_handler(
  +            XSP_Package => $package,
  +            XSP_Line => $key,
  +            XSP_Debug => 1,
  +    );
  +    
  +    my $parser = AxKit::XSP::SAXParser->new(
  +            Handler => $handler,
  +    );
  +
  +    local $Apache::AxKit::Language::XSP::ResNamespaces = $r->dir_config('XSPResNamespaces');
  +
  +   	return $parser->parse($to_parse);
  +}
  +
   sub handler {
       my $class = shift;
       my ($r, $xml, undef, $last_in_chain) = @_;
  @@ -1188,8 +1210,7 @@
     );
   
   sub has_changed {
  -    my $class = shift;
  -    my $mtime = shift;
  +    my ($package, $mtime, $r, $key) = @_;
       return 1;
   }
   
  @@ -1197,6 +1218,11 @@
       my $class = shift;
       my ($r, $cgi) = @_;
       return '';
  +}
  +
  +sub enable_cache{
  +	my ($package, $r, $key) = @_;
  +	return 0;
   }
   
   sub handler {
  
  
  
  No                   revision
  No                   revision
  1.1.2.1   +296 -0    xml-axkit/lib/Apache/AxKit/Pipeline/Attic/Cache.pm
  
  
  
  
  1.1.2.1   +42 -0     xml-axkit/lib/Apache/AxKit/Pipeline/Attic/Head.pm
  
  
  
  
  1.1.2.1   +123 -0    xml-axkit/lib/Apache/AxKit/Pipeline/Attic/Language.pm
  
  
  
  
  1.1.2.1   +164 -0    xml-axkit/lib/Apache/AxKit/Pipeline/Attic/LibXSLT.pm
  
  
  
  
  1.1.2.1   +123 -0    xml-axkit/lib/Apache/AxKit/Pipeline/Attic/Trace.pm
  
  
  
  
  1.1.2.1   +56 -0     xml-axkit/lib/Apache/AxKit/Pipeline/Attic/Transformer.pm
  
  
  
  
  1.1.2.1   +261 -0    xml-axkit/lib/Apache/AxKit/Pipeline/Attic/XSP.pm
  
  
  
  
  No                   revision
  No                   revision
  1.7.2.1   +10 -1     xml-axkit/t/conf/extra.last.conf.in
  
  Index: extra.last.conf.in
  ===================================================================
  RCS file: /home/cvs/xml-axkit/t/conf/extra.last.conf.in,v
  retrieving revision 1.7
  retrieving revision 1.7.2.1
  diff -u -r1.7 -r1.7.2.1
  --- extra.last.conf.in	19 Oct 2003 16:09:36 -0000	1.7
  +++ extra.last.conf.in	20 Oct 2003 20:58:01 -0000	1.7.2.1
  @@ -11,7 +11,7 @@
   
   eval { require XML::LibXSLT; };
   unless ($@) {
  -    $AxAddStyleMap = "text/xsl Apache::AxKit::Language::LibXSLT";
  +    $AxAddStyleMap = "text/xsl Apache::AxKit::Pipeline::LibXSLT";
       $has_libxslt = 1;
   }
   
  @@ -133,5 +133,14 @@
   	SetHandler axkit
   	AxResetProcessors
   	AxAddProcessor text/xsl /style/uri/axkit/subrequest.xsl
  +</Location>
  +
  +<Location "/pipeline/cache/01.xml">
  +	SetHandler axkit
  +	AxNoCache off
  +	AxCacheDir .cache
  +	PerlSetVar AxCacheDebugHeaders 1
  +	AxResetProcessors
  +	AxAddProcessor text/xsl /style/pipeline/cache/01.xsl
   </Location>
   
  
  
  
  No                   revision
  No                   revision
  1.1.2.1   +2 -0      xml-axkit/t/htdocs/pipeline/cache/Attic/01.xml
  
  
  
  
  No                   revision
  No                   revision
  1.1.2.1   +9 -0      xml-axkit/t/htdocs/style/pipeline/cache/Attic/01.xsl
  
  
  
  
  No                   revision
  No                   revision
  1.1.2.1   +25 -0     xml-axkit/t/pipeline/Attic/01cache.t
  
  
  
  
  No                   revision
  No                   revision
  1.1.4.1   +1 -1      xml-axkit/t/xslt-basic/02_include.t
  
  Index: 02_include.t
  ===================================================================
  RCS file: /home/cvs/xml-axkit/t/xslt-basic/02_include.t,v
  retrieving revision 1.1
  retrieving revision 1.1.4.1
  diff -u -r1.1 -r1.1.4.1
  --- 02_include.t	26 May 2003 01:41:28 -0000	1.1
  +++ 02_include.t	20 Oct 2003 20:58:02 -0000	1.1.4.1
  @@ -7,7 +7,7 @@
   
   sub test_basic {
       my $resp = GET '/xslt-basic/02_include.xml' ;
  -    #warn "GOT CONTENT:" . $resp->content();
  +#    warn "GOT CONTENT:" . $resp->content();
       return 0 unless $resp->content =~ /Included overrides default/gi;
       return 1;
   }