Revision: 35 Author: matt Date: 2006-08-03 15:24:29 +0000 (Thu, 03 Aug 2006)
Log Message: ----------- XPathScript support Modified Paths: -------------- trunk/etc/axkit.conf trunk/lib/AxKit2/Processor.pm trunk/plugins/serve_cgi Added Paths: ----------- trunk/demo/xpathscript/ trunk/demo/xpathscript/index.xml trunk/demo/xpathscript/no_wrapper.xps trunk/demo/xpathscript/non_xml_output.xps trunk/demo/xpathscript/passthru.xps trunk/demo/xpathscript/stylesheet.xps trunk/demo/xpathscript/test.xml trunk/lib/AxKit2/Transformer/XPathScript.pm trunk/plugins/demo/serve_xpathscript Added: trunk/demo/xpathscript/index.xml =================================================================== --- trunk/demo/xpathscript/index.xml 2006-08-02 22:15:08 UTC (rev 34) +++ trunk/demo/xpathscript/index.xml 2006-08-03 15:24:29 UTC (rev 35) @@ -0,0 +1 @@ +<q>lll</q> Added: trunk/demo/xpathscript/no_wrapper.xps =================================================================== --- trunk/demo/xpathscript/no_wrapper.xps 2006-08-02 22:15:08 UTC (rev 34) +++ trunk/demo/xpathscript/no_wrapper.xps 2006-08-03 15:24:29 UTC (rev 35) @@ -0,0 +1 @@ +<html><body><blink><%~ / %></blink></body></html> Added: trunk/demo/xpathscript/non_xml_output.xps =================================================================== --- trunk/demo/xpathscript/non_xml_output.xps 2006-08-02 22:15:08 UTC (rev 34) +++ trunk/demo/xpathscript/non_xml_output.xps 2006-08-03 15:24:29 UTC (rev 35) @@ -0,0 +1 @@ +This is some raw data. It could be pdf, binaries, whatever. Added: trunk/demo/xpathscript/passthru.xps =================================================================== --- trunk/demo/xpathscript/passthru.xps 2006-08-02 22:15:08 UTC (rev 34) +++ trunk/demo/xpathscript/passthru.xps 2006-08-03 15:24:29 UTC (rev 35) @@ -0,0 +1 @@ +<%~ / %> Added: trunk/demo/xpathscript/stylesheet.xps =================================================================== --- trunk/demo/xpathscript/stylesheet.xps 2006-08-02 22:15:08 UTC (rev 34) +++ trunk/demo/xpathscript/stylesheet.xps 2006-08-03 15:24:29 UTC (rev 35) @@ -0,0 +1,7 @@ +<xpathscript:wrapper + xmlns:xpathscript="http://babyl.dyndns.org/xpathscript" + xpathscript:type="text/html"> +<doc> +<%= "Hello world!" %> +</doc> +</xpathscript:wrapper> Added: trunk/demo/xpathscript/test.xml =================================================================== --- trunk/demo/xpathscript/test.xml 2006-08-02 22:15:08 UTC (rev 34) +++ trunk/demo/xpathscript/test.xml 2006-08-03 15:24:29 UTC (rev 35) @@ -0,0 +1 @@ +<doc>Blob</doc> Modified: trunk/etc/axkit.conf =================================================================== --- trunk/etc/axkit.conf 2006-08-02 22:15:08 UTC (rev 34) +++ trunk/etc/axkit.conf 2006-08-03 15:24:29 UTC (rev 35) @@ -38,4 +38,11 @@ Plugin demo/serve_tal </Location> + <Location /xpathscript> + DocumentRoot demo/xpathscript + Plugin demo/serve_xpathscript + XPathScript_Stylesheet demo/xpathscript/no_wrapper.xps + XPathScript_OutputType text/html + </Location> + </Server> Modified: trunk/lib/AxKit2/Processor.pm =================================================================== --- trunk/lib/AxKit2/Processor.pm 2006-08-02 22:15:08 UTC (rev 34) +++ trunk/lib/AxKit2/Processor.pm 2006-08-03 15:24:29 UTC (rev 35) @@ -6,12 +6,13 @@ use Exporter (); our @ISA = qw(Exporter); -our @EXPORT = qw(XSP XSLT TAL Output Render); +our @EXPORT = qw(XSP XSLT TAL XPathScript); use XML::LibXML; use AxKit2::Transformer::XSP; use AxKit2::Transformer::XSLT; use AxKit2::Transformer::TAL; +use AxKit2::Transformer::XPathScript; our $parser = XML::LibXML->new(); @@ -121,10 +122,10 @@ return AxKit2::Transformer::TAL->new($stylesheet); } -sub Output { +sub XPathScript { + my $stylesheet = shift || die "XPathScript requires a stylesheet"; + my $output_style = shift; + return AxKit2::Transformer::XPathScript->new($stylesheet, $output_style); } -sub Render { -} - 1; \ No newline at end of file Added: trunk/lib/AxKit2/Transformer/XPathScript.pm =================================================================== --- trunk/lib/AxKit2/Transformer/XPathScript.pm 2006-08-02 22:15:08 UTC (rev 34) +++ trunk/lib/AxKit2/Transformer/XPathScript.pm 2006-08-03 15:24:29 UTC (rev 35) @@ -0,0 +1,80 @@ +package AxKit2::Transformer::XPathScript; + +use strict; +use warnings; + +use XML::XPathScript; + +use base qw(AxKit2::Transformer); + +sub new { + my $class = shift; + + my $stylesheet = shift; + my $output_style = shift; + + return bless { stylesheet => $stylesheet, + output_style => $output_style }, $class; +} + +sub transform { + my $self = shift; + my ($pos, $processor) = @_; + + warn 'in transform'; + + my $dom = $processor->dom; + + my $xps = XML::XPathScript->new( stylesheetfile => $self->{stylesheet} ); + my $parser = XML::LibXML->new; + my $result = $xps->transform( $dom ); + + my $out_dom; + unless ( eval { $out_dom = $parser->parse_string( $result ) } ) { + $out_dom = $parser->parse_string( + '<xpathscript:wrapper ' + .'xmlns:xpathscript="http://babyl.dyndns.org/xpathscript" ' + .'xpathscript:type="cdata">' + .'<![CDATA[' + . $result + . ']]></xpathscript:wrapper>' ); + } + + return $out_dom, sub { $self->output(@_) }; +} + +sub output { + my ($self, $client, $dom) = @_; + + warn 'in output'; + + my $out; + my $ct = 'text/xml'; + + if ( my( $root ) = eval { $dom->findnodes( '/xpathscript:wrapper' ) } ) { + warn "xpathscript:wrapper"; + $ct = $root->getAttribute( 'type' ) + if $root->getAttribute( 'type' ); + if ( $ct eq 'cdata' ) { + $ct = 'text/plain'; + $out = $root->textContent; + } + else { + $out .= $_->toString for $root->childNodes; + } + } + else { + warn "pure XML, baby"; + $out = $dom->toStringHTML; + } + + # XPathScript_OutputStyle trumps all + $ct = $self->{output_style} if $self->{output_style}; + + $client->headers_out->header('Content-Length', length($out)); + $client->headers_out->header( 'Content-Type' => $ct ); + $client->send_http_headers; + $client->write($out); +} + +1; \ No newline at end of file Added: trunk/plugins/demo/serve_xpathscript =================================================================== --- trunk/plugins/demo/serve_xpathscript 2006-08-02 22:15:08 UTC (rev 34) +++ trunk/plugins/demo/serve_xpathscript 2006-08-03 15:24:29 UTC (rev 35) @@ -0,0 +1,57 @@ +#!/usr/bin/perl -w + +sub init { + my $self = shift; + + $self->register_config( XPathScript_Stylesheet + => sub { $self->xpathscript_stylesheet(@_) } ); + $self->register_config( XPathScript_OutputType + => sub { $self->xpathscript_output_style(@_) } ); +} + +sub xpathscript_output_style { + my ($self, $conf, $style) = @_; + + my $key = $self->plugin_name . '::outputstyle'; + + if ( $style ) { + $conf->notes($key, $style ); + } + else { + $style = $conf->notes( $key ); + } + + $self->log( LOGDEBUG, "output type is $style" ); + + return $style; +} + +sub xpathscript_stylesheet { + my ($self, $conf, $stylesheet) = @_; + + my $key = $self->plugin_name . '::stylesheet'; + + if ( $stylesheet ) { + $conf->notes($key, $stylesheet); + } + else { + $stylesheet = $conf->notes( $key ); + } + + $self->log( LOGDEBUG, "stylesheet is $stylesheet" ); + + return $stylesheet; +} + +sub hook_xmlresponse { + my ($self, $input) = @_; + + $self->log( LOGDEBUG, 'XPathScript Transform' ); + + my $stylefile = $self->xpathscript_stylesheet($self->config); + my $output_style = $self->xpathscript_output_style($self->config); + + my $out = $input->transform(XPathScript($stylefile, $output_style)); + + return OK, $out; +} \ No newline at end of file Modified: trunk/plugins/serve_cgi =================================================================== --- trunk/plugins/serve_cgi 2006-08-02 22:15:08 UTC (rev 34) +++ trunk/plugins/serve_cgi 2006-08-03 15:24:29 UTC (rev 35) @@ -72,21 +72,36 @@ # TODO: PATH_INFO, CONTENT_LENGTH, CONTENT_TYPE, COOKIE } -use POSIX qw(dup2); - -sub hook_response { - my ($self) = @_; +sub run_this_uri { + my $self = shift; my $hd = $self->client->headers_in; my $match = $self->matchfiles($self->config); $self->log(LOGDEBUG, "looking for CGIs matching: $match"); - return DECLINED unless $hd->filename =~ /$match/; + return unless $hd->filename =~ /$match/; $self->log(LOGDEBUG, $hd->filename, " matches CGI regexp"); - return DECLINED unless -x $hd->filename; + return unless -x $hd->filename; + return 1; +} + +sub hook_body_data { + my ($self, $bdata) = @_; + # TODO: Save to a temp fh. Re-open STDIN on that FH when we exec the cgi +} + +use POSIX qw(dup2); + +sub hook_response { + my ($self) = @_; + + my $hd = $self->client->headers_in; + + return DECLINED unless $self->run_this_uri; + $self->log(LOGDEBUG, "running ", $hd->filename, " as a CGI"); local %ENV;