File Coverage

blib/lib/RDF/Helper/RDFTrine.pm
Criterion Covered Total %
statement 18 51 35.2
branch 0 12 0.0
condition n/a
subroutine 6 14 42.8
pod n/a
total 24 77 31.1


line stmt bran cond sub pod time code
1             package RDF::Helper::RDFTrine;
2 11     11   10450 use Moose;
  11         17  
  11         147  
3 11     11   55457 use MooseX::Aliases;
  11         10408  
  11         36  
4              
5 11     11   358620 use RDF::Trine;
  11         16  
  11         493  
6 11     11   47 use Cwd;
  11         15  
  11         576  
7 11     11   50 use RDF::Helper::Statement;
  11         16  
  11         280  
8 11     11   39 use Data::Dumper;
  11         22  
  11         11337  
9              
10             has query_interface => (
11             isa => 'Str',
12             is => 'ro',
13             alias => ['QueryInterface'],
14             default => 'RDF::Helper::RDFQuery'
15             );
16              
17             has Model => (
18             isa => 'RDF::Trine::Model',
19             accessor => 'model',
20             lazy => 1,
21             builder => '_build_model'
22             );
23              
24             sub _build_model {
25 0     0     RDF::Trine::Model->new( RDF::Trine::Store::Memory->new() );
26             }
27              
28             has namespaces => (
29             isa => 'HashRef',
30             is => 'ro',
31             alias => ['Namespaces'],
32             builder => '_build_namespaces'
33             );
34              
35             sub _build_namespaces {
36 0     0     { rdf => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', };
37             }
38              
39             has _NS => ( isa => 'HashRef', is => 'ro', );
40              
41             has ExpandQNames => ( isa => 'Bool', is => 'ro' );
42              
43             with qw(RDF::Helper::API RDF::Helper::PerlConvenience);
44              
45             has base_uri => (
46             isa => 'Str',
47             is => 'ro',
48             alias => ['BaseURI'],
49             default => sub {
50             'file:' . getcwd();
51             }
52             );
53              
54             sub BUILD {
55 0     0     my ( $self, $args ) = @_;
56 0 0         unless ( defined( $self->namespaces->{'#default'} ) ) {
57 0           $self->namespaces->{'#default'} = $self->BaseURI;
58             }
59              
60 0           my %foo = reverse %{ $self->namespaces };
  0            
61 0           $self->{_NS} = \%foo;
62             }
63              
64             sub new_native_resource {
65 0     0     my $self = shift;
66 0           my $val = shift;
67 0           return RDF::Trine::Node::Resource->new($val);
68             }
69              
70             sub new_native_literal {
71 0     0     my $self = shift;
72 0           my ( $val, $lang, $type ) = @_;
73 0           return RDF::Trine::Node::Literal->new( $val, $lang, $type );
74             }
75              
76             sub new_native_bnode {
77 0     0     my $self = shift;
78 0           my $id = shift;
79 0           return RDF::Trine::Node::Blank->new($id);
80             }
81              
82             sub assert_literal {
83 0     0     my $self = shift;
84 0           my ( $s, $p, $o ) = @_;
85              
86 0           my ( $subj, $pred, $obj ) =
87             $self->normalize_triple_pattern( $s, $p, undef );
88 0           my @nodes = map { $self->helper2native($_) } ( $subj, $pred );
  0            
89              
90 0 0         $obj =
    0          
91             ref($o)
92             ? $o->does('RDF::Helper::Node::API')
93             ? $self->helper2native($o)
94             : $o
95             : $self->new_native_literal("$o");
96 0           push @nodes, $obj;
97 0           $self->model->add_statement( RDF::Trine::Statement->new(@nodes) );
98             }
99              
100             sub assert_resource {
101 0     0     my $self = shift;
102 0           my ( $s, $p, $o ) = @_;
103              
104 0           my ( $subj, $pred, $obj ) =
105             $self->normalize_triple_pattern( $s, $p, undef );
106 0           my @nodes = map { $self->helper2native($_) } ( $subj, $pred );
  0            
107              
108 0 0         $obj =
    0          
    0          
109             ref($o)
110             ? $o->does('RDF::Helper::Node::API')
111             ? $self->helper2native($o)
112             : $o
113             : $self->new_native_resource(
114             $self->ExpandQNames ? $self->qname2resolved($o) : $o );
115              
116 0           push @nodes, $obj;
117 0           $self->model->add_statement( RDF::Trine::Statement->new(@nodes) );
118             }
119              
120             sub add_statement {
121             my $self = shift;
122             my $statement = shift;
123              
124             my @nodes = ();
125             foreach my $type qw( subject predicate object ) {
126             push @nodes, $self->helper2native( $statement->$type );
127             }
128             $self->model->add_statement( RDF::Trine::Statement->new(@nodes) );
129             }
130              
131             sub remove_statements {
132             my $self = shift;
133              
134             my $del_count = 0;
135              
136             my $e = $self->get_enumerator(@_);
137             while ( my $s = $e->next ) {
138             my @nodes = ();
139             foreach my $type qw( subject predicate object ) {
140             push @nodes, $self->helper2native( $s->$type );
141             }
142              
143             $self->model->remove_statement( RDF::Trine::Statement->new(@nodes) );
144             $del_count++;
145             }
146              
147             return $del_count;
148             }
149              
150             sub update_node {
151             my $self = shift;
152             my ( $s, $p, $o, $new ) = @_;
153              
154             my $update_method = undef;
155              
156             # first, try to grok the type form the incoming node
157              
158             if ( ref($new) and $new->does('RDF::Trine::Node::API') ) {
159             if ( $new->is_literal ) {
160             $update_method = 'update_literal';
161             }
162             elsif ( $new->is_resource or $new->is_blank ) {
163             $update_method = 'update_resource';
164             }
165             }
166              
167             unless ($update_method) {
168             foreach my $stmnt ( $self->get_statements( $s, $p, $o ) ) {
169             my $obj = $stmnt->object;
170             if ( $obj->is_literal ) {
171             $update_method = 'update_literal';
172             }
173             elsif ( $obj->is_resource or $obj->is_blank ) {
174             $update_method = 'update_resource';
175             }
176             else {
177             warn "updating unknown node type, falling back to literal.";
178             $update_method = 'update_literal';
179             }
180             }
181             }
182             return $self->$update_method( $s, $p, $o, $new );
183             }
184              
185             sub get_enumerator {
186             my $self = shift;
187             my ( $s, $p, $o ) = @_;
188              
189             my ( $subj, $pred, $obj ) = $self->normalize_triple_pattern( $s, $p, $o );
190              
191             my @nodes = map { $self->helper2native($_) } ( $subj, $pred, $obj );
192              
193             return RDF::Helper::RDFTrine::Enumerator->new(
194             statement => RDF::Trine::Statement->new(@nodes),
195             model => $self->model,
196             );
197             }
198              
199             #---------------------------------------------------------------------
200             # Batch inclusions
201             #---------------------------------------------------------------------
202              
203             sub include_rdfxml {
204             my $self = shift;
205             my %args = @_;
206             my $p = RDF::Trine::Parser->new('rdfxml');
207              
208             my $base_uri = $self->BaseURI;
209              
210             if ( defined( $args{filename} ) ) {
211             $p->parse_file_into_model( $base_uri, $args{filename}, $self->model() );
212             }
213             elsif ( defined( $args{xml} ) ) {
214             $p->parse_into_model( $base_uri, $args{xml}, $self->model() );
215             }
216             else {
217             die
218             "Missing argument. Yous must pass in an 'xml' or 'filename' argument";
219             }
220             return 1;
221             }
222              
223             #---------------------------------------------------------------------
224             # Sub-object Accessors
225             #---------------------------------------------------------------------
226              
227             sub serialize {
228             my $self = shift;
229             my %args = @_;
230              
231             $args{format} ||= 'rdfxml';
232              
233             my %namespaces = %{$self->namespaces};
234             delete $namespaces{'#default'};
235             my $serializer = RDF::Trine::Serializer->new( $args{format},
236             namespaces => \%namespaces,
237             base_uri => $self->base_uri );
238              
239             if ( $args{filename} ) {
240             return $serializer->serialize_model_to_file( $args{filename},
241             $self->model );
242             }
243             else {
244             return $serializer->serialize_model_to_string( $self->model );
245             }
246             }
247              
248             1;
249              
250             #---------------------------------------------------------------------
251             # RDF::Trine-specific enumerator
252             #---------------------------------------------------------------------
253              
254             package RDF::Helper::RDFTrine::Enumerator;
255             use Moose;
256             use RDF::Trine::Statement;
257             use RDF::Helper::Statement;
258              
259             sub new {
260             my $proto = shift;
261             my %args = @_;
262             my $class = ref($proto) || $proto;
263             die "Not enough args" unless $args{model};
264             my $statement = delete $args{statement}
265             || RDF::Trine::Statement->new( undef, undef, undef );
266             my $self = bless \%args, $class;
267             $self->{stream} = $self->{model}->get_statements( $statement->nodes );
268             return $self;
269             }
270              
271             sub next {
272             my $self = shift;
273             my $in = undef;
274             if ( defined $self->{stream} && !$self->{stream}->end ) {
275             $in = $self->{stream}->current;
276             $self->{stream}->next;
277             }
278              
279             unless ($in) {
280             ;
281             delete $self->{stream};
282             return undef;
283             }
284              
285             my $s = undef;
286             my @nodes = ();
287             foreach my $type qw( subject predicate object ) {
288             push @nodes, process_node( $in->$type );
289             }
290             return RDF::Helper::Statement->new(@nodes);
291             }
292              
293             sub process_node {
294             my $in = shift;
295              
296             my $out = undef;
297             if ( $in->is_resource ) {
298             $out = RDF::Helper::Node::Resource->new( uri => $in->uri_value );
299             }
300             elsif ( $in->is_blank ) {
301             $out =
302             RDF::Helper::Node::Blank->new( identifier => $in->blank_identifier );
303             }
304             else {
305             my $type_uri = undef;
306             if ( my $uri = $in->literal_datatype ) {
307            
308             $type_uri = blessed($uri)
309             ? $uri->can('as_string')
310             ? $uri->as_string
311             : confess "$uri is not something we can coerce"
312             : $uri;
313              
314             }
315             $out = RDF::Helper::Node::Literal->new(
316             value => $in->literal_value,
317             language => $in->literal_value_language,
318             datatype => $type_uri
319             );
320             }
321             return $out;
322             }
323             1;
324              
325             __END__
326              
327             =head1 NAME
328              
329             RDF::Helper::RDFReland - RDF::Helper bridge for RDF::Trine
330              
331             =head1 SYNOPSIS
332              
333             my $model = RDF::Trine::Model->new(
334             RDF::Trine::Storage->new( %storage_options )
335             );
336              
337             my $rdf = RDF::Helper->new(
338             Namespaces => \%namespaces,
339             BaseURI => 'http://domain/NS/2004/09/03-url#'
340             );
341              
342             =head1 DESCRIPTION
343              
344             RDF::Helper::RDFTrine is the bridge class that connects RDF::Helper's facilites to RDF::Trine and should not be used directly.
345              
346             See L<RDF::Helper> for method documentation
347              
348             =head1 AUTHOR
349              
350             Kip Hampton, khampton@totalcinema.com
351              
352             =head1 COPYRIGHT
353              
354             Copyright (c) 2004 Kip Hampton.
355             =head1 LICENSE
356              
357             This module is free sofrware; you can redistribute it and/or modify
358             it under the same terms as Perl itself.
359              
360             =head1 SEE ALSO
361              
362             L<RDF::Helper> L<RDF::Trine>.
363              
364             =cut
365