File: Helper.pm

package info (click to toggle)
librdf-helper-perl 2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 336 kB
  • sloc: perl: 1,827; makefile: 11
file content (521 lines) | stat: -rw-r--r-- 17,383 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
package RDF::Helper;
use 5.10.1;
use Moose;
our $VERSION = '2.0';

use RDF::Helper::Statement;
use RDF::Helper::Object;

has backend => (
    does     => 'RDF::Helper::API',
    is       => 'ro',
    required => 1,
    handles  => 'RDF::Helper::API',
);

sub BUILDARGS {
    my $this  = shift;
    my $args  = $this->SUPER::BUILDARGS(@_);
    return $args if $args->{backend};

    my $class = delete $args->{BaseInterface};

    $class = 'RDF::Redland'
      if (!$class
        && $args->{Model}
        && $args->{Model}->isa('RDF::Redland::Model') );

    given ($class) {
        when (qr/RDF::Helper::.*/) { }
        when ('RDF::Redland') { $class = 'RDF::Helper::RDFRedland'; };
        default { $class = 'RDF::Helper::RDFTrine' }
    }

    Class::MOP::load_class($class);
    my $backend = $class->new(%$args);
    return { backend => $backend };
}

1;
__END__

=head1 NAME

RDF::Helper - Provide a consistent, high-level API for working with RDF with Perl

=head1 SYNOPSIS

  use RDF::Helper;

  my $rdf = RDF::Helper->new(
      BaseInterface => 'RDF::Trine',
      namespaces => {
          dct => 'http://purl.org/dc/terms/',
          rdf => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
         '#default' => "http://purl.org/rss/1.0/",
     }
  );

=head1 DESCRIPTION

This module intends to simplify, normalize and extend Perl's existing
facilities for interacting with RDF data.

RDF::Helper's goal is to offer a syntactic sugar which will enable
developers to work more efficiently. To achieve this, it implements
methods to work with RDF in a way that would be familiar to Perl
programmers who are less experienced with RDF.

It builds on L<RDF::Trine>, which in turn provides the low-level API
which is closer to RDF.

=head1 CONSTRUCTOR OPTIONS

  my $rdf = RDF::Helper->new(
      BaseInterface => 'RDF::Trine',
      namespaces => {
          dc => 'http://purl.org/dc/terms/',
          rdf => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
         '#default' => "http://purl.org/rss/1.0/",
     },
     ExpandQNames => 1
  );

=head2 BaseInterface

The C<BaseInterface> option expects a string that corresponds to the
class name of the underlying Perl RDF library that will be used by
this instance of the Helper. L<RDF::Trine> is the default, but
C<RDF::Redland> is retained as an option for historical reasons, but
may be removed in the future. If you have a Redland-based database,
you can use L<RDF::Trine::Store::Redland>.

=head2 Model

The C<Model> option expects a blessed instance object of the RDF model
that will be operated on with this instance of the Helper. Obviously,
the type of object passed should correspond to the L<BaseInterface>
used (L<RDF::Trine::Model> for a BaseInterface of L<RDF::Trine>,
etc.). If this option is omitted, a new, in-memory model will be
created.

=head2 namespaces

The C<namespaces> option expects a hash reference of prefix/value
pairs for the namespaces that will be used with this instance of the
Helper. The special '#default' prefix is reserved for setting the
default namespace.

For convenience, the L<RDF::Helper::Constants> class will export a
number of useful constants that can be used to set the namespaces for
common grammars:

  use RDF::Helper;
  use RDF::Helper::Constants qw(:rdf :rss1 :foaf);

  my $rdf = RDF::Helper->new(
      BaseInterface => 'RDF::Trine',
      namespaces => {
          rdf => RDF_NS,
          rss => RSS1_NS,
          foaf => FOAF_NS
     },
     ExpandQNames => 1
  );

=head2 ExpandQNames

Setting a non-zero value for the C<ExpandQNames> option configures the
current instance of the Helper to allow for qualified URIs to be used
in the arguments to many of the Helper's convenience methods. For
example, given the L<namespaces> option for the previous example, with
C<ExpandQNames> turned on, the following will work as expected.

  $rdf->assert_resource( $uri, 'rdf:type', 'foaf:Person' );

With C<ExpandQNames> turned off, you would have to pass the full URI
for both the C<rdf:type> predicate, and the C<foaf:Person> object to
achieve the same result.

=head2 base_uri

If specified, this option sets what the base URI will be when working
with so called abbreviated URIs, like C<#me>.  If you do not specify
an explicit base_uri option, then one will be created automatically
for you.  See
L<http://www.w3.org/TR/rdf-syntax-grammar/#section-Syntax-ID-xml-base>
for more information on abbreviated URIs.

=head1 METHODS

=head2 new_resource

  $res = $rdf->new_resource($uri)

Creates and returns a new resource object that represents the supplied
URI.  In many cases this is not necessary as the methods available in
L<RDF::Helper> will automatically convert a string URI to the
appropriate object type in the back-end RDF implementation.

=head2 new_literal

  $lit = $rdf->new_literal($text)
  $lit = $rdf->new_literal($text, $lang)
  $lit = $rdf->new_literal($text, $lang, $type)

Creates and returns a new literal text object that represents the
supplied string.  In many cases this is not necessary as the methods
available in L<RDF::Helper> will automatically convert the value to
the appropriate object type in the back-end RDF implementation.

When it is necessary to explicitly create a literal object is when you
want to specify the language or datatype of the text string.  The
datatype argument expects a Resource object or a string URI.

=head2 new_bnode

  $bnode = $rdf->new_bnode()

Creates and returns a new "Blank Node" that can be used as the subject
or object in a new statement.

=head2 assert_literal

  $rdf->assert_literal($subject, $predicate, $object)

This method will assert, or "insert", a new statement whose value, or "object", is a literal.

Both the subject and predicate arguments can either take a URI object, a URI string.

Additionally, if you used the L</ExpandQNames> option when creating
the L<RDF::Helper> object, you can use QNames in place of the subject
and predicate values.  For example, "rdf:type" would be properly
expanded to its full URI value.

=head2 assert_resource

  $rdf->assert_resource($subject, $predicate, $object)

This method will assert, or "insert", a new statement whose value, or "object", is a resource.

The subject, predicate and object arguments can either take a URI object, or a URI string.

Like L</assert_literal>, if you used the L</ExpandQNames> option when
creating the L<RDF::Helper> object, you can use QNames in place of any
of the arguments to this method.  For example, "rdf:type" would be
properly expanded to its full URI value.

=head2 remove_statements

  $count = $rdf->remove_statements()
  $count = $rdf->remove_statements($subject)
  $count = $rdf->remove_statements($subject, $predicate)
  $count = $rdf->remove_statements($subject, $predicate, $object)

This method is used to remove statements from the back-end RDF model
whose constituent parts match the supplied arguments.  Any of the
arguments can be omitted, or passed in as C<undef>, which means any
value for that triple part will be matched and removed.

For instance, if values for the predicate and object are given, but
the subject is left as "undef", then any statement will be removed
that matches the supplied predicate and object.  If no arguments are
supplied, then all statements in the RDF model will be removed.

The number of statements that were removed in this operation is returned.

=head2 update_node

  $rdf->update_node($subject, $predicate, $object, $new_object)

This method is used when you wish to change the object value of an
existing statement.  This method acts as an intelligent wrapper around
the L</update_literal> and L</update_resource> methods, and will try
to auto-detect what type of object is currently in the datastore, and
will try to set the new value accordingly.  If it can't make that
determination it will fallback to L</update_literal>.

Keep in mind that if you need to change a statement from having a
Resource to a Literal, or vice versa, as its object, then you may need
to invoke the appropriate update method directly.

=head2 update_literal

  $rdf->update_literal($subject, $predicate, $object, $new_object)

Updates an existing statement's literal object value to a new one.
For more information on the operation of this method, see
L</update_node>.

=head2 update_resource

  $rdf->update_resource($subject, $predicate, $object, $new_object)

Updates an existing statement's resource object value to a new one.
For more information on the operation of this method, see
L</update_node>.

=head2 get_statements

  @stmts = $rdf->get_statements()
  @stmts = $rdf->get_statements($subject)
  @stmts = $rdf->get_statements($subject, $predicate)
  @stmts = $rdf->get_statements($subject, $predicate, $object)

This method is used to fetch and return statements from the back-end
RDF model whose constituent parts match the supplied arguments.  Any
of the arguments can be omitted, or passed in as C<undef>, which means
any value for that triple part will be matched and returned.

For instance, if values for the predicate and object are given, but
the subject is left as "undef", then any statement will be returned
that matches the supplied predicate and object.  If no arguments are
supplied, then all statements in the RDF model will be returned.

Depending on which back-end type being used, different object types
will be returned.  For instance, if L<RDF::Trine> is used, then all
the returned objects will be of type L<RDF::Trine::Statement>.

=head2 get_triples

  @stmts = $rdf->get_triples()
  @stmts = $rdf->get_triples($subject)
  @stmts = $rdf->get_triples($subject, $predicate)
  @stmts = $rdf->get_triples($subject, $predicate, $object)

This method functions in the same way as L</get_statements>, except
instead of the statements being represented as objects, the
statement's values are broken down into plain strings and returned as
an anonymous array.  Therefore, an individual element of the returned
array may look like this:

  [ "http://some/statement/uri", "http://some/predicate/uri", "some object value" ]


=head2 resourcelist

  @subjects = $rdf->resourcelist()
  @subjects = $rdf->resourcelist($predicate)
  @subjects = $rdf->resourcelist($predicate, $object)

This method returns the unique list of subject URIs from within the
RDF model that optionally match the predicate and/or object arguments.
Like in L</get_statements>, either or all of the arguments to this
method can be C<undef>.

=head2 exists

  $result = $rdf->exists()
  $result = $rdf->exists($subject)
  $result = $rdf->exists($subject, $predicate)
  $result = $rdf->exists($subject, $predicate, $object)

Returns a boolean value indicating if any statements exist in the RDF
model that matches the supplied arguments.

=head2 count

  $count = $rdf->count()
  $count = $rdf->count($subject)
  $count = $rdf->count($subject, $predicate)
  $count = $rdf->count($subject, $predicate, $object)

Returns the number of statements that exist in the RDF model that
matches the supplied arguments.  If no arguments are supplied, it
returns the total number of statements in the model are returned.

=head2 include_model

  $rdf->include_model($model)

Include the contents of another, already opened, RDF model into the
current model.

=head2 include_rdfxml

  $rdf->include_rdfxml(xml => $xml_string)
  $rdf->include_rdfxml(filename => $file_path)

This method will import the RDF statements contained in an RDF/XML
document, either from a file or a string, into the current RDF model.
If a L</base_uri> was specified in the L<RDF::Helper>
L<constructor|/"CONSTRUCTOR OPTIONS">, then that URI is used as the
base for when the supplied RDF/XML is imported.  For instance, if the
hash notation is used to reference an RDF node
(e.g. C<E<lt>rdf:Description rdf:about="#dahut"/E<gt>>), the
L</base_uri> will be prepended to the C<rdf:about> URI.

=head2 serialize

  $string = $rdf->serialize()
  $string = $rdf->serialize(format => 'ntriple')
  $rdf->serialize(filename => 'out.rdf')
  $rdf->serialize(filename => 'out.n3', format => 'ntriple')

Serializes the back-end RDF model to a string, using the specified
format type, or defaulting to abbreviated RDF/XML.  The serialization
types depends on which RDF back-end is in use.  The L<RDF::Trine>
support within L<RDF::Helper> supports the following serialization
types:

=over 4

=item * ntriples

=item * nquads

=item * rdfxml

=item * rdfjson

=item * ntriples-canonical

=item * turtle

=back

=head2 new_query

  $query_object = $obj->new_query( $query, [$base_uri, $lang_uri, $lang_name] );

Returns an instance of the class defined by the L<QueryInterface>
argument passed to the constructor (or the default class for the base
interface if none is explicitly set) that can be used to query the
currently selected model.

=head1 PERLISH CONVENIENCE METHODS

=head2 property_hash

  $hash_ref = $rdf->property_hash($subject)

For instances when you don't know what properties are bound to an RDF
node, or when it is too cumbersome to iterate over the results of a
L</get_triples> method call, this method can be used to return all the
properties and values bound to an RDF node as a hash reference.  The
key name will be the predicate URI (QName-encoded if a matching
namespace is found), and the value will be the object value of the
given predicate.  Multiple object values for the same predicate URI
will be returned as an array reference.

It is important to note that this is a read-only dump from the RDF
model.  For a "live" alternative to this, see L</tied_property_hash>.

=head2 deep_prophash

  $hashref = $rdf->deep_prophash($subject)

This method is similar to the L</property_hash> method, except this
method will recurse over children nodes, in effect creating a nested
hashref data structure representing a node and all of its associations.

B<Note:> This method performs no checks to ensure that it doesn't get
stuck in a deep recursion loop, so be careful when using this.

=head2 tied_property_hash

  $hash_ref = $rdf->tied_property_hash($subject)
  $hash_ref = $rdf->tied_property_hash($subject, \%options)

Like L</property_hash>, this method returns a hash reference
containing the predicates and objects bound to the given subject URI.
This method differs however in that any changes to the hash will
immediately be represented in the RDF model.  So if a new value is
assigned to an existing hash key, if a new key is added, or a key is
deleted from the hash, that will transparently be represented as
updates, assertions or removal operations against the model.

Optionally a hash can be passed to this method when tieing a property
hash to give additional instructions to the
L<RDF::Helper::RDFRedland::TiedPropertyHash> object.  Please see the
documentation in that class for more information.

=head2 get_object

  $obj = $rdf->get_object($subject, %options)
  $obj = $rdf->get_object($subject, \%options)

Returns an instance of L<RDF::Helper::Object> bound to the given
subject URI.  This exposes that RDF node as an object-oriented class
interface, allowing you to interact with and change that RDF node and
its properties using standard Perl-like accessor methods.  For more
information on the use of this method, please see
L<RDF::Helper::Object>.


=head2 arrayref2rdf

  $obj->arrayref2rdf(\@list, $subject, $predicate);
  $obj->arrayref2rdf(\@list, undef, $predicate);

Asserts a list of triples with the the subject C<$subject>, predicate
C<$predicate> and object(s) contained in C<\@list>. It the subject is
undefined, a new blank node will be used.

=head2 hashref2rdf

  $object->hashref2rdf( \%hash );
  $object->hashref2rdf( \%hash, $subject );

This method is the reverse of L</property_hash> and L</deep_prophash>
in that it accepts a Perl hash reference and unwinds it into a set
of triples in the RDF store. If the C<$subject> is missing or
undefined a new blank node will be used.


=head2 hashlist_from_statement

  @list = $rdf->hashlist_from_statement()
  @list = $rdf->hashlist_from_statement($subject)
  @list = $rdf->hashlist_from_statement($subject, $predicate)
  @list = $rdf->hashlist_from_statement($subject, $predicate, $object)

Accepting a sparsely populated triple pattern as its argument, this
methods return a list of subject/hash reference pairs for all
statements that match the pattern. Each member in the list will have
the following structure:

  [ $subject, $hash_reference ]

=head1 ACCESSOR METHODS

=head2 model

  $model = $rdf->model()
  $rdf->model($new_model)

An accessor method that can be used to retrieve or set the back-end
RDF model that this L<RDF::Helper> instance uses.

=head2 query_interface

  $iface = $rdf->query_interface()
  $rdf->query_interface($iface)

Accessor method that is used to either set or retrieve the current
class name that should be used for composing and performing queries.

=head1 SEE ALSO

L<RDF::Helper::Object>; L<RDF::Trine>, L<RDF::Redland>; L<RDF::Query>


=head1 SUPPORT

There is a mailing list at L<http://lists.perlrdf.org/listinfo/dev>.

A bunch of people are also hanging out in C<#perlrdf> on C<irc.perl.org>.


=head1 AUTHOR

Kip Hampton, E<lt>khampton@totalcinema.com<gt>

=head1 COPYRIGHT AND LICENSE

Copyright 2004-2011 by Kip Hampton, Chris Prather, Mike Nachbaur

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut