#Copyright Massachusetts Institute of technology, 1998.
#Written by Eric Prud'hommeaux for the World Wide Web Consortium

# $Id: ResultSetRenderer.pm,v 1.7 2007/03/11 02:19:05 eric Exp $

use strict;
require Exporter;
#require AutoLoader;

$W3C::Rdf::RdfDB::REVISION = '$Id: ResultSetRenderer.pm,v 1.7 2007/03/11 02:19:05 eric Exp $ ';

package W3C::Rdf::ResultSetRenderer;
use vars qw($VERSION $DSLI @ISA @TODO @EXPORT_OK);
@ISA = qw(W3C::Util::NamedParmObject Exporter); # AutoLoader);
@TODO = qw();
@EXPORT_OK = qw();
$VERSION = 0.95;
$DSLI = 'adpO';

use W3C::Util::Exception;
use W3C::XML::XmlSerializer;
use W3C::Rdf::Atoms qw($RDF_SCHEMA_URI $ATTRIBUTION_SCHEMA_URI);

sub new {
    my ($proto, @parms) = @_;
    my $class = ref($proto) || $proto;
    my $self = $class->SUPER::new(@parms);
    my $rdfNS = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
    $self->{VARS} = [];
    $self->{LastIndex} = $self->{-sorted} ? 0 : undef;
    $self->{STR} = "\@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
\@prefix rs:      <http://www.w3.org/2001/sw/DataAccess/tests/result-set#> .

[]  rdf:type    rs:ResultSet ;
";
    return $self;
}

sub addHeaders {
    my ($self, @data) = @_;
    my $data = &_normalizeData(\@data);
    push (@{$self->{VARS}}, @$data);
    my $varsStr = join(", ", map {"\"$_\""} @$data);
    $self->{STR} .= "    rs:resultVariable
                $varsStr ";
}
sub addData {
    my ($self, @data) = @_;
    $self->_addData(@data);
}
sub addRow {
    my ($self, @data) = @_;
    $self->_addData(@data);
}
sub underline {
    my ($self, $index) = @_;
    &throw(new W3C::Util::NotImplementedException());
}
sub setBoolean {
    my ($self, $val) = @_;
    my $truthStr = $val ? 'true' : 'false';
    $self->{STR} .= "    rs:boolean \"$truthStr\"^^xsd:boolean .\n";
}
sub toString {
    my ($self) = @_;
    return $self->{STR}.'.';
}
sub _normalizeData { # static
    my ($data) = @_;
    if (ref $data->[0] eq 'ARRAY') {
	$data = [@{$data->[0]}];
    }
    return $data;
}
sub _addData {
    my ($self, @data) = @_;
    my $data = &_normalizeData(\@data);
    my @strData;
    for (my $i = 0; $i < @$data; $i++) {
	my $dataStr = $data->[$i]->toString();
	push (@strData, "[ rs:value    $dataStr ;
                                rs:variable \"$self->{VARS}[$i]\"
                              ]");
    }
    my $bindingStr = join(" ,
                              ", @strData);
    my $ordinalStr = '';
    if ($self->{-sorted}) {
	++$self->{LastIndex};
	$ordinalStr = " ;
                  rs:index  $self->{LastIndex}";
    }
    $self->{STR} .= ";
    rs:solution [ rs:binding  $bindingStr$ordinalStr
                ] ";
}

1;

__END__

=head1 NAME

W3C::Rdf::ResultSetRenderer - serialize RDF graphs as RDF/XML

=head1 SYNOPSIS

  use W3C::Rdf::Atoms;
  use W3C::Rdf::RdfDB;
  require W3C::Rdf::ResultSetRenderer;
  my $atoms = new W3C::Rdf::Atoms();
  my $rdfDB = new W3C::Rdf::RdfDB(-atomDictionary => $atoms);
  my $algae2 = new W3C::Rdf::Algae2(-atomDictionary => $atoms);
  my $serializer = new W3C::Rdf::ResultSetRenderer(-atomDictionary => $atoms);
  my $iterator = $rdfDB->makeSerializerIterator($statements, $algae2);
  $iterator->iterate($serializer);
  print $serializer->getText();

=head1 DESCRIPTION

C<W3C::Rdf::RdfDB>'s C<W3C::Rdf::RdfDB::SerializerIterator> calls
C<W3C::Rdf::StatementsSerializer> to generate RDF/XML.

This module is part of the W3C::Rdf CPAN module.

=head1 CONSTRUCTOR

=over 4

=item new ( ATOMS [, FLAGS] )

Creates an C<W3C::Rdf::ResultSetRenderer>.  This must be passed an Atoms dictionary.
Attitional flags:

=back

=head1 METHODS

=over 4

=item collection()

Return whether this serializer has special code for collections. If so,
C<serializeStatements> may be called with a C<W3C::Rdf::Atoms::ListStatement>.

=item nest()

Return whether this serializer can express nested descriptions.

=item startDocument()

Follow SAX convention except there is no document locator (the serializer is
the actual owner of the document).

=item endDocument()

Follow SAX convention.

=item serializeStatements( STATEMENTS, [ ITERATOR ] )

Take a set of statements to be serialized. The C<ITERATOR> is only used if the
serializer attempts to serialize nested (statements with a subject of the
current object). The C<STATENTS> may also be ListStatemens, in which case
special code serializes a collection.

=item getText()

Return a scalar with the serialized RDF. The caller will likely write this to
a file or to a network stream in response to an HTTP GET of some virtual document.

=back

=head1 AUTHOR

Eric Prud'hommeaux <eric@w3.org>

=head1 SEE ALSO

L<W3C::Rdf::RdfDB>

=cut
