# -*- Mode: Perl -*-
#
# Statement.pm - Redland Perl RDF Statement module
#
# $Id: Statement.pm 10593 2006-03-05 08:30:38Z dajobe $
#
# Copyright (C) 2000-2005 David Beckett - http://purl.org/net/dajobe/
# Copyright (C) 2000-2005 University of Bristol - http://www.bristol.ac.uk/
#
# This package is Free Software or Open Source available under the
# following licenses (these are alternatives):
# 1. GNU Lesser General Public License (LGPL)
# 2. GNU General Public License (GPL)
# 3. Mozilla Public License (MPL)
#
# See LICENSE.html or LICENSE.txt at the top of this package for the
# full license terms.
#
#
#
package RDF::Redland::Statement;
use strict;
use RDF::Redland::Node;
=pod
=head1 NAME
RDF::Redland::Statement - Redland RDF Statement Class
=head1 SYNOPSIS
use RDF::Redland;
my $statement1=new RDF::Redland::Statement($statement);
my $statement2=new RDF::Redland::Statement($subject,$predicate,$object);
...
if($statement->subject->equals($node)) {
...
}
=head1 DESCRIPTION
Manipulate RDF statements which comprise three RDF::Redland::Node objects.
Also used for I<partial> statements which can have empty parts and
are used for matching statements in statement queries of the
model - see the L<RDF::Redland::Model>.
=cut
######################################################################
=pod
=head1 CONSTRUCTORS
=over
=item new NODE NODE NODE|STATEMENT
Create a new statement from nodes or copy an existing statement.
If three I<NODE>s are given, make a new statement from them.
Each Node can be a Redland::RDF:Node, a Redland::RDF::URI,
a perl URI or a string literal.
Otherwise I<STATEMENT> must be an existing statement to copy.
=cut
sub new ($;$$$) {
my($proto,@args)=@_;
my $class = ref($proto) || $proto;
my $self = {};
if(scalar(@args)==3) {
for (@args) {
next if !defined $_;
if(my $class=ref $_) {
$_=&RDF::Redland::Node::_ensure($_);
die "Cannot make a Node from an object of class $class\n"
unless $_;
} else {
$_=&RDF::Redland::CORE::librdf_new_node_from_uri_string($RDF::Redland::World->{WORLD},$_);
}
} # end for args
$self->{STATEMENT}=&RDF::Redland::CORE::librdf_new_statement_from_nodes($RDF::Redland::World->{WORLD}, @args);
} elsif (scalar(@args) == 1) {
my $s=$args[0];
if(!ref($s) || ref($s) ne 'RDF::Redland::Statement') {
die "RDF::Redland::Statement::new - Cannot copy a statement object not of class RDF::Redland::Statement\n";
}
$self->{STATEMENT}=&RDF::Redland::CORE::librdf_new_statement_from_statement($RDF::Redland::World->{WORLD}, $s->{STATEMENT});
} elsif (scalar(@args) == 0) {
$self->{STATEMENT}=&RDF::Redland::CORE::librdf_new_statement($RDF::Redland::World->{WORLD});
} else {
die "RDF::Redland::Statement::new - bad arguments. Either give one argument to copy a statement or three to build from nodes.\n";
}
return undef if !$self->{STATEMENT};
bless ($self, $class);
return $self;
}
=item clone
Copy a RDF::Redland::Statement.
=cut
sub clone ($$) {
my($statement)=@_;
my $class = ref($statement);
my $self = {};
if(!$class || $class ne 'RDF::Redland::Statement') {
die "RDF::Redland::Statement::clone - Cannot copy a statement object not of class RDF::Redland::Statement\n";
}
$self->{STATEMENT}=&RDF::Redland::CORE::librdf_new_statement_from_statement($statement->{STATEMENT});
return undef if !$self->{STATEMENT};
bless ($self, $class);
return $self;
}
sub new_from_statement ($$) {
my($proto,$statement)=@_;
return $statement->clone;
}
sub new_from_nodes ($$$$) {
my($proto,$s,$p,$o)=@_;
return RDF::Redland::Statement->new($s,$p,$o);
}
# internal constructor to build a new object from a statement created
# by librdf e.g. from the result of a stream->next operation
# It always makes a new Redland Statement
sub _new_from_object ($$) {
my($proto,$object)=@_;
return undef if !$object;
my $class = ref($proto) || $proto;
my $self = {};
$self->{STATEMENT}=&RDF::Redland::CORE::librdf_new_statement_from_statement($object);
bless ($self, $class);
return $self;
}
=pod
=back
=cut
sub DESTROY ($) {
my $self=shift;
warn "RDF::Redland::Statement DESTROY $self\n" if $RDF::Redland::Debug;
if($self->{STATEMENT}) {
&RDF::Redland::CORE::librdf_free_statement($self->{STATEMENT});
}
warn "RDF::Redland::Statement DESTROY done\n" if $RDF::Redland::Debug;
}
=head1 METHODS
=over
=item subject [SUBJECT]
Get/set the statement subject. When a RDF::Redland::Node I<SUBJECT>
is given, sets the subject of the statement, otherwise returns a
reference to the statement RDF::Redland::Node subject.
=cut
sub subject ($;$) {
my($self,$subject)=@_;
return RDF::Redland::Node->_new_from_object(&RDF::Redland::CORE::librdf_statement_get_subject(shift->{STATEMENT}))
unless $subject;
my $s=&RDF::Redland::CORE::librdf_new_node_from_node($subject->{NODE});
return &RDF::Redland::CORE::librdf_statement_set_subject($self->{STATEMENT},$s);
}
=item predicate [PREDICATE]
Get/set the statement predicate. When RDF::Redland::Node
I<PREDICATE> is given, sets the predicate of the statement, otherwise
returns a reference to the statement RDF::Redland::Node predicate.
=cut
sub predicate ($;$) {
my($self,$predicate)=@_;
return RDF::Redland::Node->_new_from_object(&RDF::Redland::CORE::librdf_statement_get_predicate(shift->{STATEMENT}))
unless $predicate;
my $p=&RDF::Redland::CORE::librdf_new_node_from_node($predicate->{NODE});
return &RDF::Redland::CORE::librdf_statement_set_predicate($self->{STATEMENT},$p);
}
=item object [OBJECT]
Get/set the statement object. When RDF::Redland::Node I<OBJECT> is given, sets
the object of the statement, otherwise returns a reference to the
statement RDF::Redland::Node object.
=cut
sub object ($;$) {
my($self,$object)=@_;
return RDF::Redland::Node->_new_from_object(&RDF::Redland::CORE::librdf_statement_get_object(shift->{STATEMENT}))
unless $object;
my $o=&RDF::Redland::CORE::librdf_new_node_from_node($object->{NODE});
return &RDF::Redland::CORE::librdf_statement_set_object($self->{STATEMENT},$o);
}
=item as_string
Return the statement formatted as a string (UTF-8 encoded).
=cut
sub as_string ($) {
&RDF::Redland::CORE::librdf_statement_to_string(shift->{STATEMENT});
}
=item equals STATEMENT
Return non zero if this statement is equal to STATEMENT
=cut
sub equals ($$) {
my($self,$statement)=@_;
&RDF::Redland::CORE::librdf_statement_equals($self->{STATEMENT}, $statement->{STATEMENT});
}
=pod
=back
=head1 OLD METHODS
=over
=item new_from_nodes SUBJECT PREDICATE OBJECT
Create a new RDF::Redland::Statement with the given
RDF::Redland::Node objects as parts (or undef when empty for a
I<partial> statement). Use instead:
$a=new RDF::Redland::Statement($subject, $predicate, $object);
=item new_from_statement STATEMENT
Create a new RDF::Redland::Statement object from
RDF::Redland::Statement I<STATEMENT> (copy constructor).
Use instead:
$s=$old_statement->clone;
=cut
=back
=head1 SEE ALSO
L<RDF::Redland::Node>
=head1 AUTHOR
Dave Beckett - http://purl.org/net/dajobe/
=cut
1;