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...@sergeant.org on 2006/08/03 17:24:51 UTC

[SVN] [35] XPathScript support

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;