File Coverage

blib/lib/RDF/aREF.pm
Criterion Covered Total %
statement 56 63 88.8
branch 20 32 62.5
condition 11 17 64.7
subroutine 13 13 100.0
pod 4 4 100.0
total 104 129 80.6


line stmt bran cond sub pod time code
1             package RDF::aREF;
2 7     7   1339904 use strict;
  7         17  
  7         187  
3 7     7   40 use warnings;
  7         13  
  7         169  
4 7     7   80 use v5.10;
  7         23  
5              
6             our $VERSION = '0.27';
7              
8 7     7   1694 use RDF::aREF::Query;
  7         16  
  7         192  
9 7     7   37 use RDF::aREF::Decoder;
  7         10  
  7         242  
10 7     7   1998 use RDF::aREF::Encoder;
  7         16  
  7         227  
11 7     7   42 use Scalar::Util qw(blessed reftype);
  7         14  
  7         321  
12 7     7   36 use Carp qw(croak);
  7         11  
  7         236  
13              
14 7     7   32 use parent 'Exporter';
  7         11  
  7         31  
15             our @EXPORT = qw(decode_aref encode_aref aref_query aref_query_map);
16             our %EXPORT_TAGS = (all => [@EXPORT]);
17              
18             our @CARP_NOT = qw(RDF::aREF::Query RDF::aREF::Decoder RDF::aREF::Encoder);
19              
20             sub decode_aref(@) { ## no critic
21 22     22 1 14028 my ($aref, %options) = @_;
22 22         129 RDF::aREF::Decoder->new(%options)->decode($aref);
23             }
24              
25             sub encode_aref(@) { ## no critic
26 8     8 1 6292 my ($source, %options) = @_;
27 8         58 my $encoder = RDF::aREF::Encoder->new(%options);
28 8   100     53 my $aref = $options{to} // {};
29              
30 8 50 66     160 if (blessed $source and $source->isa('RDF::Trine::Iterator')) {
    50 66        
    100 66        
    50 33        
    100 66        
    50          
31 0         0 $encoder->add_iterator( $source, $aref );
32             } elsif (blessed $source and $source->DOES('Attean::API::TripleIterator')) {
33 0         0 $encoder->add_iterator( $source, $aref );
34             } elsif (blessed $source and $source->isa('RDF::Trine::Model')) {
35 2         13 $encoder->add_iterator( $source->as_stream, $aref );
36             } elsif (blessed $source and $source->DOES('Attean::API::TripleStore')) {
37 0         0 $encoder->add_iterator( $source->get_triples, $aref );
38             } elsif (ref $source and reftype $source eq 'HASH') {
39 4         13 $encoder->add_hashref( $source, $aref );
40             } elsif (!ref $source) {
41 2         4 eval { require RDF::Trine::Model; require RDF::Trine::Parser };
  2         320  
  2         1029576  
42 2 50       7 croak "RDF::Trine missing: encoding aREF from URL or file not supported!" if $@;
43 2         12 my $model = RDF::Trine::Model->new;
44             # TODO: directly use iterator
45 2 50       202 if ($source =~ qr{^https?://}) {
    50          
46 0         0 RDF::Trine::Parser->parse_url_into_model($source, $model);
47             } elsif (-f $source) {
48 2         19 my $parser = RDF::Trine::Parser->guess_parser_by_filename($source);
49 2         48 $parser->parse_file_into_model("file://$source", $source, $model)
50             } else {
51 0         0 croak 'invalid RDF graph, given as string';
52             }
53 2         33792 $encoder->add_iterator( $model->as_stream, $aref );
54             }
55            
56 8         1348 return $aref;
57             }
58              
59             sub aref_query(@) { ## no critic
60 26 100   26 1 14468 my ($graph, $origin, @queries) = @_ < 3 ? ($_[0], undef, $_[1]) : @_;
61 26         137 RDF::aREF::Query->new( query => join '|', @queries )->apply($graph, $origin);
62             }
63              
64             sub aref_query_map(@) { ## no critic
65 1 50   1 1 269 my ($graph, $origin, $map) = @_ < 3 ? ($_[0], undef, $_[1]) : @_;
66              
67 1         2 my %record;
68            
69 1         6 while (my ($query, $field) = each %$map) {
70 2 50       8 my @values = aref_query( $origin ? ($graph, $origin, $query)
71             : ($graph, $query) );
72 2 50       33 if (@values) {
73 2 100       498 if ($record{$field}) {
74 1 50       4 if (ref $record{$field}) {
75 0         0 push @{$record{$field}}, @values;
  0         0  
76             } else {
77 1         7 $record{$field} = [ $record{$field}, @values ];
78             }
79             } else {
80 1 50       8 $record{$field} = @values > 1 ? \@values : $values[0];
81             }
82             }
83             }
84              
85 1         5 \%record;
86             }
87              
88             1;
89             __END__
90              
91             =head1 NAME
92              
93             RDF::aREF - Another RDF Encoding Form
94              
95             =begin markdown
96              
97             # STATUS
98              
99             [![Build Status](https://travis-ci.org/nichtich/RDF-aREF.png)](https://travis-ci.org/nichtich/RDF-aREF)
100             [![Coverage Status](https://coveralls.io/repos/nichtich/RDF-aREF/badge.png)](https://coveralls.io/r/nichtich/RDF-aREF)
101             [![Kwalitee Score](http://cpants.cpanauthors.org/dist/RDF-aREF.png)](http://cpants.cpanauthors.org/dist/RDF-aREF)
102              
103             =end markdown
104              
105             =head1 SYNOPSIS
106              
107             use RDF::aREF;
108              
109             my $rdf = {
110             _id => 'http://example.com/people#alice',
111             foaf_name => 'Alice Smith',
112             foaf_age => '42^xsd_integer',
113             foaf_homepage => [
114             {
115             _id => 'http://personal.example.org/',
116             dct_modified => '2010-05-29^xsd_date',
117             },
118             'http://work.example.com/asmith/',
119             ],
120             foaf_knows => {
121             dct_description => 'a nice guy@en',
122             },
123             };
124              
125             decode_aref( $rdf,
126             callback => sub {
127             my ($subject, $predicate, $object, $language, $datatype) = @_;
128             ...
129             }
130             );
131            
132             my @lastmod = aref_query $rdf, 'foaf_homepage.dct_modified^';
133              
134             my $model = RDF::Trine::Model->new;
135             decode_aref( $rdf, callback => $model );
136             print RDF::Trine::Serializer->new('Turtle')->serialize_model_to_string($model);
137              
138             my $model = RDF::Trine::Model->new;
139             RDF::Trine::Parser->parse_url_into_model($url, $model);
140             my $aref = encode_aref $model;
141              
142             =head1 DESCRIPTION
143              
144             B<aREF> (L<another RDF Encoding Form|http://gbv.github.io/aREF/>) is an
145             encoding of RDF graphs in form of arrays, hashes, and Unicode strings. This
146             module provides methods for decoding from aREF data to RDF triples
147             (L<RDF::aREF::Decoder>), for encoding RDF data in aREF (L<RDF::aREF::Encoder>),
148             and for querying parts of an RDF graph (L<RDF::aREF::Query>).
149              
150             =head1 EXPORTED FUNCTIONS
151              
152             The following functions are exported by default.
153              
154             =head2 decode_aref $aref [, %options ]
155              
156             Decodes an aREF document given as hash reference with L<RDF::aREF::Decoder>.
157             Equivalent to C<< RDF::aREF::Decoder->new(%options)->decode($aref) >>.
158              
159             =head2 encode_aref $graph [, %options ]
160              
161             Construct an aREF subject mapfrom an RDF graph. The L<RDF::aREF::Encoder> for
162             possible options. The C<$graph> can be supplied as:
163              
164             =over
165              
166             =item
167              
168             instance of L<RDF::Trine::Model>
169              
170             =item
171              
172             instance of L<RDF::Trine::Model::Iterator>
173              
174             =item
175              
176             an URL or a filename (only if L<RDF::Trine> is installed)
177              
178             =item
179              
180             instance of L<Attean::API::TripleIterator> (experimental)
181              
182             =item
183              
184             instance of L<Attean::API::TripleStore> (experimental)
185              
186             =item
187              
188             hash reference with L<RDF/JSON|http://www.w3.org/TR/rdf-json/> format (as
189             returned by method C<as_hashref> in L<RDF::Trine::Model>)
190              
191             =back
192              
193             =head2 aref_query $graph, [ $origin ], @queries
194              
195             Query parts of an aREF data structure by L<aREF query
196             expressions|http://gbv.github.io/aREF/aREF.html#aref-query> and return a list.
197             See L<RDF::aREF::Query> for details.
198              
199             =head2 aref_query_map( $graph, [ $origin ], $query_map )
200              
201             Map parts of an aREF data structure to a flat key-value structure.
202              
203             =head1 SEE ALSO
204              
205             =over
206              
207             =item
208              
209             aREF is specified at L<http://github.com/gbv/aREF>.
210              
211             =item
212              
213             See L<Catmandu::RDF> for an application of this module.
214              
215             =item
216              
217             Usee L<RDF::Trine> for more elaborated handling of RDF data in Perl.
218              
219             =item
220              
221             See L<RDF::YAML> for a similar (outdated) RDF encoding in YAML.
222              
223             =back
224              
225             =head1 COPYRIGHT AND LICENSE
226              
227             Copyright Jakob Voss, 2014-
228              
229             This library is free software; you can redistribute it and/or modify it under
230             the same terms as Perl itself.
231              
232             =cut