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