#!/usr/bin/perl
#Copyright Massachusetts Institute of technology, 2006.
#Written by Eric Prud'hommeaux for the World Wide Web Consortium
#This file is PUBLIC DOMAIN.

# SRXParser.pm -- CMParser (XML Parser) for http://www.w3.org/2005/sparql-results .
# 
# $Id: SRXParser.pm,v 1.5 2007-07-31 21:40:56 eric Exp $

use strict;
package W3C::Rdf::SRXParser;
@W3C::Rdf::SRXParser::ISA = qw(W3C::XML::CMParser);

use W3C::XML::CMParser;

use vars qw($srx $xsd $rdf $rs $xml $CM);
$srx = 'http://www.w3.org/2005/sparql-results#';
$xsd = 'http://www.w3.org/2001/XMLSchema#';
$rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
$rs  = 'http://www.w3.org/2001/sw/DataAccess/tests/result-set#';
$xml = 'http://www.w3.org/XML/1998/namespace';

$CM = { _name => '--root--', 
    "{$srx}sparql" => { _name => "{$srx}sparql", 
	_start => sub {
	    my ($self, $data) = @_;
	}, 
	"{$srx}head" => { _name => "{$srx}head", 
	    _start => sub {
		my ($self, $data) = @_;
	    }, 
	    "{$srx}link" => {
	    }, 
	    "{$srx}variable" => { _name => "{$srx}variable", 
		_start => sub {
		    my ($self, $data) = @_;
		    push (@{$self->{VARS}}, $data->{Attributes}{'{}name'}{Value});
		    # push (@{$self->{VARS}}, $data->{Attributes}{'{}name'}{Value});
		}, 
	    },
	    _end => sub {
		my ($self, $data) = @_;
		&{$self->{-vars}}(@{$self->{VARS}});
	    }, 
	}, 
	"{$srx}boolean" => { _name => "{$srx}boolean", 
	    _chars => sub {
		my ($self, $data) = @_;
		&{$self->{-boolean}}($data->{Data});
	    }
	}, 
	"{$srx}results" => { _name => "{$srx}results", 
	    _start => sub {
		my ($self, $data) = @_;
	    }, 
	    "{$srx}result" => { _name => "{$srx}result", 
		_start => sub {
		    my ($self, $data) = @_;
		    $self->{ByVar} = {};
		    # push (@{$self->{RESULTS}}, {});
		}, 
		"{$srx}binding" => { _name => "{$srx}binding", 
		    _start => sub {
			my ($self, $data) = @_;
			$self->{Name} = $data->{Attributes}{'{}name'}{Value};
			# $self->{CURVAR} = $data->{Attributes}{'{}name'}{Value};
		    }, 
		    "{$srx}uri" => { _name => "{$srx}uri", 
			_chars => sub {
			    my ($self, $data) = @_;
			    $self->{ByVar}{$self->{Name}} = $self->{-atomDictionary}->getAbsoluteUri($data->{Data});
			    # $self->{RESULTS}[-1]{$self->{CURVAR}} = $data->{Data};
			}
		    }, 
		    "{$srx}bnode" => { _name => "{$srx}bnode", 
			_chars => sub {
			    my ($self, $data) = @_;
			    my $label = $data->{Data};
			    $self->{ByVar}{$self->{Name}} = $self->{BNodeMap}->{$label};
			    if (!$self->{ByVar}{$self->{Name}}) {
				$self->{ByVar}{$self->{Name}} = $self->{BNodeMap}->{$label} = $self->{-atomDictionary}->createBNode($self->{Attrib});
			    }
			    # $self->{RESULTS}[-1]{$self->{CURVAR}} = $data->{Data};
			}
		    }, 
		    "{$srx}literal" => { _name => "{$srx}literal", 
			_start => sub {
			    my ($self, $data) = @_;
			    my $dt = $data->{Attributes}{'{}datatype'}{Value};
			    $self->{DATATYPE} = $dt ? $self->{-atomDictionary}->getAbsoluteUri($dt) : undef;
			    $self->{LANG} = $data->{Attributes}{"{$xml}lang"}{Value};
			}, 
			_chars => sub {
			    my ($self, $data) = @_;
			    $self->{Literal} .= $data->{Data};
			}, 
			_end => sub {
			    my ($self, $data) = @_;
			    $self->{ByVar}{$self->{Name}} = $self->{-atomDictionary}->getString($self->{Literal}, $self->{DATATYPE}, 'PLAIN', $self->{LANG});
			    $self->{Literal} = undef;
			    $self->{DATATYPE} = undef;
			    $self->{LANG} = undef;
			    # $self->{RESULTS}[-1]{$self->{CURVAR}} = str;
			}
		    }
		}, 
		_end => sub {
		    my ($self, $data) = @_;
		    &{$self->{-bindings}}(%{$self->{ByVar}});
		    delete $self->{ByVar};
		    # push (@{$self->{RESULTS}}, {});
		}, 
	    }
	}
    } 
};

sub new {
    my ($proto, $attrib, $handlerStack, %args) = @_;
    my $class = ref($proto) || $proto;
    my $self = {Attrib => $attrib, # for bNode creation
		HandlerStack => $handlerStack, 
		Stack => [$CM], 
	        NSHelper => $handlerStack->get_namespace_helper(), 
		%args};
    bless ($self, $class);
    return $self;
}


1;

__END__

=head1 NAME

W3C::Rdf::SRXParser - parse SPARQL XML Results into 

=head1 SYNOPSIS

    require W3C::Rdf::SRXParser;
    require W3C::XML::HandlerStack;
    require XML::SAX::ParserFactory;
    my $handlerStack = new W3C::XML::HandlerStack();
    $self->{NSHelper} = $handlerStack->get_namespace_helper();
    my $srxHandler = new W3C::Rdf::SRXParser($self, $handlerStack, -location => $location, 
                         -rdfDB => $self->{-rdfDB}, -atomDictionary => $self->{-atomDictionary});
    $handlerStack->set_handler($srxHandler);
    my $srxParser = XML::SAX::ParserFactory->parser(Handler => $handlerStack);
    $srxParser->parse_string($bytes);

=cut

