File Coverage

blib/lib/RDF/SKOS.pm
Criterion Covered Total %
statement 68 85 80.0
branch 14 24 58.3
condition n/a
subroutine 19 27 70.3
pod 21 22 95.4
total 122 158 77.2


line stmt bran cond sub pod time code
1             package RDF::SKOS;
2              
3 5     5   86652 use warnings;
  5         10  
  5         437  
4 5     5   27 use strict;
  5         11  
  5         159  
5              
6 5     5   1075 use Data::Dumper;
  5         7411  
  5         370  
7              
8 5     5   1920 use RDF::SKOS::Concept;
  5         10  
  5         159  
9 5     5   1735 use RDF::SKOS::Scheme;
  5         11  
  5         4844  
10              
11             =head1 NAME
12              
13             RDF::SKOS - SKOS - Simple Knowledge Organization System
14              
15             =head1 SYNOPSIS
16              
17             use RDF::SKOS;
18             my $skos = new RDF::SKOS;
19              
20             # adding one
21             $skos->concept ('aaa' => { prefLabels => [ [ 'xxx', 'de' ] ] });
22              
23             # regain it
24             my $c = $skos->concept ('aaa');
25              
26             # get all of them
27             my @cs = $skos->concepts;
28              
29             # label stuff
30             @labels = $c->prefLabels;
31             @labels = $c->altLabels;
32             @labels = $c->hiddenLabels;
33              
34             @labels = $c->notes;
35             @labels = $c->scopeNotes;
36             @labels = $c->definitions;
37             @labels = $c->examples;
38             @labels = $c->historyNotes;
39             @labels = $c->editorialNotes;
40             @labels = $c->changeNotes;
41              
42             # broader/narrower
43             @cs = $c->narrower
44             @cs = $c->narrowerTransitive
45             @cs = $c->broader
46             @cs = $c->broaderTransitive
47              
48             # associated
49             @cs = $c->related
50             @cs = $c->relatedTransitive
51              
52             # get all schemes
53             @ss = $skos->schemes
54             # get a particular
55             $sch = $skos->scheme ('some_scheme');
56             # find top-level concepts
57             @tops = $skos->topConcepts ('some_scheme');
58              
59              
60             =head1 DESCRIPTION
61              
62             !!! DEVELOPER RELEASE (THERE MAY BE DRAGONS) !!!
63              
64             !!! PLEASE SEE THE README FOR LIMITATIONS !!!
65              
66             SKOS is a model for expressing very basic concept schemes, much simpler than Topic Maps or RDF. This
67             includes subject headings, taxonomies, folksonomies. For a primer see
68              
69             =begin html
70              
71             SKOS Primer
72              
73             =end html
74              
75             =head2 Overview
76              
77             This package suite supports SKOS in that:
78              
79             =over
80              
81             =item
82              
83             It provides packages with particular SKOS data,
84              
85             =item
86              
87             It implements SKOS on top of various RDF stores, so that you can read RDF and enjoy an I
88             view> on top of that,
89              
90             =item
91              
92             Or you can derive your own subclasses of the generic L, especially for the case
93             where you have a different format.
94              
95             =back
96              
97             =head2 Concept Identification
98              
99             This implementation assumes that each concept has a unique ID. That is simply a scalar.
100              
101             =head2 Caveats
102              
103             Following things are not yet added:
104              
105             =over
106              
107             =item
108              
109             At the moment there is mostly read-only support. You can add concepts to the SKOS, but there is no
110             proper interface for added/removing concepts, or schemes.
111              
112             =item
113              
114             There is also no support for collections yet.
115              
116             =item
117              
118             And none for all *Match relationships between concepts.
119              
120             =item
121              
122             And most of the SKOS constraints are not yet honored.
123              
124             =back
125              
126             If you need any of that, please throw obscene amounts of (good) chocolate into my direction. Or
127             write a patch! No. Better send chocolate.
128              
129             =head1 INTERFACE
130              
131             =head2 Constructor
132              
133             The constructor does not expect any additional information.
134              
135             Example:
136              
137             my $skos = new RDF::SKOS;
138              
139             =cut
140              
141             sub new {
142 1     1 0 15 my $class = shift;
143 1         5 return bless {}, $class;
144             }
145              
146             =pod
147              
148             =head2 Methods
149              
150             =over
151              
152             =item B
153              
154             I<$c> = I<$skos>->concept ('xyz')
155              
156             Given the ID of the concept, this method returns an L object representing the
157             concept. If there is no such concept C will be returned.
158              
159             If - apart from the ID - another parameter is added, that must be a HASH reference carrying all the
160             attributes for that concept. That concept will be stored under this ID. If there was already
161             something there, it will be overwritten.
162              
163             =cut
164              
165             sub concept {
166 5     5 1 10269 my $self = shift;
167 5         11 my $ID = shift;
168 5         8 my $info = shift;
169 5 100       20 if ($info) {
170 3 100       33 die "concept" unless ref ($info) eq 'HASH';
171 2         21 my $c = new RDF::SKOS::Concept ($self, $ID, %$info);
172 2         20 return $self->{concepts}->{$ID} = $c;
173             } else {
174 2         7 return $self->{concepts}->{$ID};
175             }
176             }
177              
178             =pod
179              
180             =item B
181              
182             I<@concepts> = I<$skos>->concepts
183              
184             This method return a list of L objects, each for a concept in the SKOS.
185              
186             =cut
187              
188             sub concepts {
189 0     0 1 0 die "this must be implemented by a subclass";
190             }
191              
192             =back
193              
194             =head2 Scheme-Related Methods
195              
196             =over
197              
198             =item B
199              
200             I<@schemes> = I<$skos>->schemes
201              
202             This will return a list of L objects which all represent one scheme within the
203             SKOS.
204              
205             =cut
206              
207             sub schemes {
208 2     2 1 25 return ();
209             }
210              
211             =pod
212              
213             =item B
214              
215             I<$scheme> = I<$skos>->scheme (I)
216              
217             Returns the scheme object for the one with that ID.
218              
219             =cut
220              
221             sub scheme {
222 0     0 1 0 return ();
223             }
224              
225             =pod
226              
227             =item B
228              
229             I<@tops> = I<$skos>->topConcepts ('scheme_a')
230              
231             Given the ID of a concept scheme, this will return a list of L objects
232             representing the top-level concepts in that scheme.
233              
234             =cut
235              
236             sub topConcepts {
237 0     0 1 0 return ();
238             }
239              
240             =pod
241              
242             =back
243              
244             =head2 Concept-Related Methods
245              
246             All these methods expect the concept ID to be passed in as the sole parameter:
247              
248             I<@labels> = I<$skos>->prefLabels ('some-concept')
249              
250             Out comes a list of tuples. Each tuple contains first the value, then the language tag, both as
251             scalars.
252              
253             =over
254              
255             =item B
256              
257             Returns the list of preferred labels.
258              
259             =cut
260              
261             sub prefLabels {
262 2     2 1 5 my $self = shift;
263 2         4 my $cid = shift;
264 2         8 my $c = $self->{concepts}->{$cid};
265 2 50       8 return $c->{prefLabels} ? @{ $c->{prefLabels} } : ();
  2         19  
266             }
267              
268             =pod
269              
270             =item B
271              
272             Returns the list of alternative labels.
273              
274             =cut
275              
276             sub altLabels {
277 1     1 1 2 my $self = shift;
278 1         3 my $cid = shift;
279 1         3 my $c = $self->{concepts}->{$cid};
280 1 50       9 return $c->{altLabels} ? @{ $c->{altLabels} } : ();
  0         0  
281             }
282              
283             =pod
284              
285             =item B
286              
287             Returns the list of hidden labels.
288              
289             =cut
290              
291             sub hiddenLabels {
292 1     1 1 2 my $self = shift;
293 1         3 my $cid = shift;
294 1         3 my $c = $self->{concepts}->{$cid};
295 1 50       9 return $c->{hiddenLabels} ? @{ $c->{hiddenLabels} } : ();
  0         0  
296             }
297              
298             =pod
299              
300             =item B
301              
302             Returns the list of notes.
303              
304             B: No property subclassing is honored, so scopeNotes are NOT included (yet).
305              
306             =cut
307              
308             sub notes {
309 1     1 1 2 my $self = shift;
310 1         3 my $cid = shift;
311 1         4 my $c = $self->{concepts}->{$cid};
312 1 50       11 return $c->{notes} ? @{ $c->{notes} } : ();
  0         0  
313             }
314              
315             =pod
316              
317             =item B
318              
319             Returns the list of scope notes.
320              
321             =cut
322              
323             sub scopeNotes {
324 1     1 1 2 my $self = shift;
325 1         3 my $cid = shift;
326 1         6 my $c = $self->{concepts}->{$cid};
327 1 50       12 return $c->{scopeNotes} ? @{ $c->{scopeNotes} } : ();
  0         0  
328             }
329              
330             =pod
331              
332             =item B
333              
334             Returns the list of definitions.
335              
336             =cut
337              
338             sub definitions {
339 1     1 1 3 my $self = shift;
340 1         2 my $cid = shift;
341 1         3 my $c = $self->{concepts}->{$cid};
342 1 50       30 return $c->{definitions} ? @{ $c->{definitions} } : ();
  0         0  
343             }
344              
345             =pod
346              
347             =item B
348              
349             Returns the list of examples.
350              
351             =cut
352              
353             sub examples {
354 1     1 1 2 my $self = shift;
355 1         3 my $cid = shift;
356 1         3 my $c = $self->{concepts}->{$cid};
357 1 50       10 return $c->{examples} ? @{ $c->{examples} } : ();
  0         0  
358             }
359              
360             =pod
361              
362             =item B
363              
364             Returns the list of history notes.
365              
366             =cut
367              
368             sub historyNotes {
369 1     1 1 3 my $self = shift;
370 1         3 my $cid = shift;
371 1         15 my $c = $self->{concepts}->{$cid};
372 1 50       10 return $c->{historyNotes} ? @{ $c->{historyNotes} } : ();
  0         0  
373             }
374              
375             =pod
376              
377             =item B
378              
379             Returns the list of editorial notes.
380              
381             =cut
382              
383             sub editorialNotes {
384 1     1 1 2 my $self = shift;
385 1         2 my $cid = shift;
386 1         4 my $c = $self->{concepts}->{$cid};
387 1 50       9 return $c->{editorialNotes} ? @{ $c->{editorialNotes} } : ();
  0         0  
388             }
389              
390             =pod
391              
392             =item B
393              
394             Returns the list of change notes.
395              
396             =cut
397              
398             sub changeNotes {
399 1     1 1 3 my $self = shift;
400 1         3 my $cid = shift;
401 1         3 my $c = $self->{concepts}->{$cid};
402 1 50       8 return $c->{changeNotes} ? @{ $c->{changeNotes} } : ();
  0         0  
403             }
404              
405             =pod
406              
407             =back
408              
409             =head2 Taxonometrical Methods
410              
411             =over
412              
413             =item B/B
414              
415             I<$cs> = I<$skos>->narrower (I<$ID>)
416              
417             I<$cs> = I<$skos>->narrowerTransitive (I<$ID>)
418              
419             I<$cs> = I<$skos>->broader (I<$ID>)
420              
421             I<$cs> = I<$skos>->broaderTransitive (I<$ID>)
422              
423             This method expects the ID of a concept and returns a list of L objects which
424             have a C relationship to that with ID. As the semantics of I involves that it is
425             the inverse of I also these relationships are respected.
426              
427             If you want I/I to be interpreted transitively, then use the variant
428             C. That not only interprets everything transitively, it also picks up the
429             I relationships inside the SKOS object.
430              
431             B: I understand that this deviates somewhat from the standard. But it makes life easier.
432              
433             =cut
434              
435             sub narrower {
436 0     0 1 0 return ();
437             }
438              
439             =pod
440              
441             =item B
442              
443             See above
444              
445             =cut
446              
447             sub narrowerTransitive {
448 0     0 1 0 return ();
449             }
450              
451             =pod
452              
453             =item B
454              
455             See above
456              
457             =cut
458              
459             sub broader {
460 0     0 1 0 return ();
461             }
462              
463             =pod
464              
465             =item B
466              
467             See above
468              
469             =cut
470              
471             sub broaderTransitive {
472 0     0 1 0 return ();
473             }
474              
475             =pod
476              
477             =back
478              
479             =head2 Associative Methods
480              
481             =over
482              
483             =item B
484              
485             This method expects the ID of a concept and returns a list of L objects which
486             have a C relationship to that identified with ID. Note that I is always symmetric,
487             not not automatically transitive. If you want transitivity to be honored, then use the variant
488             C.
489              
490             B: This interpretation is fully SKOS compliant.
491              
492             =cut
493              
494             sub related {
495 1697     1697 1 8981 return ();
496             }
497              
498             =pod
499              
500             =item B
501              
502             See above
503              
504             =cut
505              
506             sub relatedTransitive {
507 0     0 1   return ();
508             }
509              
510             =pod
511              
512             =back
513              
514             =head1 AUTHOR
515              
516             Robert Barta, C<< >>
517              
518             =head1 BUGS
519              
520             Please report any bugs or feature requests to C, or through
521             the web interface at L. I will be notified, and then you'll
522             automatically be notified of progress on your bug as I make changes.
523              
524             =head1 COPYRIGHT & LICENSE
525              
526             Copyright 2009 Robert Barta, all rights reserved.
527              
528             This program is free software; you can redistribute it and/or modify it under the same terms as Perl
529             itself.
530              
531             =cut
532              
533             our $VERSION = '0.03';
534              
535             "against all odds";
536              
537             __END__