rdf 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/AUTHORS +1 -1
  2. data/VERSION +1 -1
  3. data/lib/rdf.rb +25 -22
  4. data/lib/rdf/enumerable.rb +554 -0
  5. data/lib/rdf/format.rb +239 -41
  6. data/lib/rdf/model/graph.rb +82 -0
  7. data/lib/rdf/{literal.rb → model/literal.rb} +47 -4
  8. data/lib/rdf/{node.rb → model/node.rb} +0 -0
  9. data/lib/rdf/{resource.rb → model/resource.rb} +0 -0
  10. data/lib/rdf/{statement.rb → model/statement.rb} +12 -0
  11. data/lib/rdf/{uri.rb → model/uri.rb} +20 -7
  12. data/lib/rdf/model/value.rb +135 -0
  13. data/lib/rdf/ntriples.rb +35 -2
  14. data/lib/rdf/ntriples/format.rb +4 -4
  15. data/lib/rdf/ntriples/reader.rb +2 -2
  16. data/lib/rdf/ntriples/writer.rb +26 -19
  17. data/lib/rdf/query.rb +4 -4
  18. data/lib/rdf/query/pattern.rb +3 -3
  19. data/lib/rdf/query/solution.rb +2 -2
  20. data/lib/rdf/query/variable.rb +3 -3
  21. data/lib/rdf/reader.rb +85 -16
  22. data/lib/rdf/repository.rb +104 -12
  23. data/lib/rdf/version.rb +1 -1
  24. data/lib/rdf/vocab.rb +171 -0
  25. data/lib/rdf/vocab/cc.rb +18 -0
  26. data/lib/rdf/vocab/dc.rb +63 -0
  27. data/lib/rdf/vocab/doap.rb +45 -0
  28. data/lib/rdf/vocab/exif.rb +168 -0
  29. data/lib/rdf/vocab/foaf.rb +69 -0
  30. data/lib/rdf/vocab/http.rb +26 -0
  31. data/lib/rdf/vocab/owl.rb +59 -0
  32. data/lib/rdf/{vocabulary → vocab}/rdf.rb +7 -1
  33. data/lib/rdf/vocab/rdfs.rb +17 -0
  34. data/lib/rdf/{vocabulary → vocab}/rss.rb +6 -1
  35. data/lib/rdf/vocab/sioc.rb +93 -0
  36. data/lib/rdf/vocab/skos.rb +36 -0
  37. data/lib/rdf/vocab/wot.rb +21 -0
  38. data/lib/rdf/vocab/xhtml.rb +9 -0
  39. data/lib/rdf/vocab/xsd.rb +58 -0
  40. data/lib/rdf/writer.rb +123 -16
  41. metadata +26 -27
  42. data/lib/rdf/graph.rb +0 -197
  43. data/lib/rdf/reader/ntriples.rb +0 -5
  44. data/lib/rdf/value.rb +0 -76
  45. data/lib/rdf/vocabulary.rb +0 -133
  46. data/lib/rdf/vocabulary/cc.rb +0 -9
  47. data/lib/rdf/vocabulary/dc.rb +0 -9
  48. data/lib/rdf/vocabulary/doap.rb +0 -9
  49. data/lib/rdf/vocabulary/exif.rb +0 -9
  50. data/lib/rdf/vocabulary/foaf.rb +0 -9
  51. data/lib/rdf/vocabulary/http.rb +0 -9
  52. data/lib/rdf/vocabulary/owl.rb +0 -9
  53. data/lib/rdf/vocabulary/rdfs.rb +0 -9
  54. data/lib/rdf/vocabulary/sioc.rb +0 -9
  55. data/lib/rdf/vocabulary/skos.rb +0 -9
  56. data/lib/rdf/vocabulary/wot.rb +0 -9
  57. data/lib/rdf/vocabulary/xhtml.rb +0 -9
  58. data/lib/rdf/vocabulary/xsd.rb +0 -9
  59. data/lib/rdf/writer/ntriples.rb +0 -5
data/AUTHORS CHANGED
@@ -1 +1 @@
1
- * Arto Bendiken <arto.bendiken@gmail.com> (Lead developer)
1
+ * Arto Bendiken <arto.bendiken@gmail.com>
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.6
1
+ 0.0.7
data/lib/rdf.rb CHANGED
@@ -1,14 +1,17 @@
1
1
  require 'rdf/version'
2
2
 
3
3
  module RDF
4
+ # RDF mixins
5
+ autoload :Enumerable, 'rdf/enumerable'
6
+
4
7
  # RDF objects
5
- autoload :Graph, 'rdf/graph'
6
- autoload :Literal, 'rdf/literal'
7
- autoload :Node, 'rdf/node'
8
- autoload :Resource, 'rdf/resource'
9
- autoload :Statement, 'rdf/statement'
10
- autoload :URI, 'rdf/uri'
11
- autoload :Value, 'rdf/value'
8
+ autoload :Graph, 'rdf/model/graph'
9
+ autoload :Literal, 'rdf/model/literal'
10
+ autoload :Node, 'rdf/model/node'
11
+ autoload :Resource, 'rdf/model/resource'
12
+ autoload :Statement, 'rdf/model/statement'
13
+ autoload :URI, 'rdf/model/uri'
14
+ autoload :Value, 'rdf/model/value'
12
15
 
13
16
  # RDF serialization
14
17
  autoload :Format, 'rdf/format'
@@ -25,21 +28,21 @@ module RDF
25
28
  autoload :Query, 'rdf/query'
26
29
 
27
30
  # RDF vocabularies
28
- autoload :Vocabulary, 'rdf/vocabulary'
29
- autoload :CC, 'rdf/vocabulary/cc'
30
- autoload :DC, 'rdf/vocabulary/dc'
31
- autoload :DOAP, 'rdf/vocabulary/doap'
32
- autoload :EXIF, 'rdf/vocabulary/exif'
33
- autoload :FOAF, 'rdf/vocabulary/foaf'
34
- autoload :HTTP, 'rdf/vocabulary/http'
35
- autoload :OWL, 'rdf/vocabulary/owl'
36
- autoload :RDFS, 'rdf/vocabulary/rdfs'
37
- autoload :RSS, 'rdf/vocabulary/rss'
38
- autoload :SIOC, 'rdf/vocabulary/sioc'
39
- autoload :SKOS, 'rdf/vocabulary/skos'
40
- autoload :WOT, 'rdf/vocabulary/wot'
41
- autoload :XHTML, 'rdf/vocabulary/xhtml'
42
- autoload :XSD, 'rdf/vocabulary/xsd'
31
+ autoload :Vocabulary, 'rdf/vocab'
32
+ autoload :CC, 'rdf/vocab/cc'
33
+ autoload :DC, 'rdf/vocab/dc'
34
+ autoload :DOAP, 'rdf/vocab/doap'
35
+ autoload :EXIF, 'rdf/vocab/exif'
36
+ autoload :FOAF, 'rdf/vocab/foaf'
37
+ autoload :HTTP, 'rdf/vocab/http'
38
+ autoload :OWL, 'rdf/vocab/owl'
39
+ autoload :RDFS, 'rdf/vocab/rdfs'
40
+ autoload :RSS, 'rdf/vocab/rss'
41
+ autoload :SIOC, 'rdf/vocab/sioc'
42
+ autoload :SKOS, 'rdf/vocab/skos'
43
+ autoload :WOT, 'rdf/vocab/wot'
44
+ autoload :XHTML, 'rdf/vocab/xhtml'
45
+ autoload :XSD, 'rdf/vocab/xsd'
43
46
 
44
47
  ##
45
48
  # @return [String] uri
@@ -0,0 +1,554 @@
1
+ module RDF
2
+ ##
3
+ # An RDF statement enumeration mixin.
4
+ #
5
+ # Classes that include this module must implement an `#each` method that
6
+ # yields {RDF::Statement RDF statements}.
7
+ #
8
+ # @example Checking whether any statements exist
9
+ # enumerable.empty?
10
+ #
11
+ # @example Checking how many statements exist
12
+ # enumerable.count
13
+ #
14
+ # @example Checking whether a specific statement exists
15
+ # enumerable.has_statement?(RDF::Statement.new(subject, predicate, object))
16
+ # enumerable.has_triple?([subject, predicate, object])
17
+ # enumerable.has_quad?([subject, predicate, object, context])
18
+ #
19
+ # @example Checking whether a specific value exists
20
+ # enumerable.has_subject?(RDF::URI.new("http://rdf.rubyforge.org/"))
21
+ # enumerable.has_predicate?(RDF::DC.creator)
22
+ # enumerable.has_object?(RDF::Literal.new("Hello!", :language => :en))
23
+ # enumerable.has_context?(RDF::URI.new("http://rubyforge.org/"))
24
+ #
25
+ # @example Enumerating all statements
26
+ # enumerable.each_statement do |statement|
27
+ # puts statement.inspect
28
+ # end
29
+ #
30
+ # @example Enumerating all statements in the form of triples
31
+ # enumerable.each_triple do |subject, predicate, object|
32
+ # puts [subject, predicate, object].inspect
33
+ # end
34
+ #
35
+ # @example Enumerating all statements in the form of quads
36
+ # enumerable.each_quad do |subject, predicate, object, context|
37
+ # puts [subject, predicate, object, context].inspect
38
+ # end
39
+ #
40
+ # @example Enumerating all values
41
+ # enumerable.each_subject { |value| puts value.inspect }
42
+ # enumerable.each_predicate { |value| puts value.inspect }
43
+ # enumerable.each_object { |value| puts value.inspect }
44
+ # enumerable.each_context { |value| puts value.inspect }
45
+ #
46
+ # @example Obtaining all statements
47
+ # enumerable.statements #=> [RDF::Statement(subject1, predicate1, object1), ...]
48
+ # enumerable.triples #=> [[subject1, predicate1, object1], ...]
49
+ # enumerable.quads #=> [[subject1, predicate1, object1, context1], ...]
50
+ #
51
+ # @example Obtaining all unique values
52
+ # enumerable.subjects #=> [subject1, subject2, subject3, ...]
53
+ # enumerable.predicates #=> [predicate1, predicate2, predicate3, ...]
54
+ # enumerable.objects #=> [object1, object2, object3, ...]
55
+ # enumerable.contexts #=> [context1, context2, context3, ...]
56
+ #
57
+ # @see RDF::Graph
58
+ # @see RDF::Repository
59
+ module Enumerable
60
+ include ::Enumerable
61
+
62
+ ##
63
+ # Returns `true` if `self` contains no RDF statements.
64
+ #
65
+ # @return [Boolean]
66
+ def empty?
67
+ empty = true
68
+ each_statement { empty = false; break }
69
+ empty
70
+ end
71
+
72
+ ##
73
+ # Returns the number of RDF statements in `self`.
74
+ #
75
+ # @return [Integer]
76
+ def count
77
+ count = 0
78
+ each_statement { count += 1 }
79
+ count
80
+ end
81
+
82
+ alias_method :size, :count
83
+ alias_method :length, :count
84
+
85
+ ##
86
+ # Returns all RDF statements.
87
+ #
88
+ # @param [Hash{Symbol => Boolean}] options
89
+ # @return [Array<Statement>]
90
+ # @see #each_statement
91
+ # @see #enum_statement
92
+ def statements(options = {})
93
+ enum_statement.to_a
94
+ end
95
+
96
+ ##
97
+ # Returns `true` if `self` contains the given RDF statement.
98
+ #
99
+ # @param [Statement] statement
100
+ # @return [Boolean]
101
+ def has_statement?(statement)
102
+ enum_statement.include?(statement)
103
+ end
104
+
105
+ ##
106
+ # Iterates the given block for each RDF statement.
107
+ #
108
+ # If no block was given, returns an enumerator.
109
+ #
110
+ # @overload each_statement
111
+ # @yield [statement]
112
+ # @yieldparam [Statement] statement
113
+ # @return [void]
114
+ #
115
+ # @overload each_statement
116
+ # @return [Enumerator]
117
+ #
118
+ # @return [void]
119
+ # @see #enum_statement
120
+ def each_statement(&block)
121
+ if block_given?
122
+ # Invoke {#each} in the containing class:
123
+ each(&block)
124
+ else
125
+ enum_statement
126
+ end
127
+ end
128
+
129
+ ##
130
+ # Returns an enumerator for {#each_statement}.
131
+ #
132
+ # @return [Enumerator]
133
+ # @see #each_statement
134
+ def enum_statement
135
+ require_enumerator!
136
+ ::Enumerable::Enumerator.new(self, :each_statement)
137
+ end
138
+
139
+ alias_method :enum_statements, :enum_statement
140
+
141
+ ##
142
+ # Returns all RDF triples.
143
+ #
144
+ # @param [Hash{Symbol => Boolean}] options
145
+ # @return [Array<Array(Resource, URI, Value)>]
146
+ # @see #each_triple
147
+ # @see #enum_triple
148
+ def triples(options = {})
149
+ enum_statement.map(&:to_triple)
150
+ end
151
+
152
+ ##
153
+ # Returns `true` if `self` contains the given RDF triple.
154
+ #
155
+ # @param [Array(Resource, URI, Value)] triple
156
+ # @return [Boolean]
157
+ def has_triple?(triple)
158
+ enum_triple.include?(triple)
159
+ end
160
+
161
+ ##
162
+ # Iterates the given block for each RDF triple.
163
+ #
164
+ # If no block was given, returns an enumerator.
165
+ #
166
+ # @overload each_triple
167
+ # @yield [subject, predicate, object]
168
+ # @yieldparam [Resource] subject
169
+ # @yieldparam [URI] predicate
170
+ # @yieldparam [Value] object
171
+ # @return [void]
172
+ #
173
+ # @overload each_triple
174
+ # @return [Enumerator]
175
+ #
176
+ # @return [void]
177
+ # @see #enum_triple
178
+ def each_triple(&block)
179
+ if block_given?
180
+ each_statement do |statement|
181
+ block.call(*statement.to_triple)
182
+ end
183
+ else
184
+ enum_triple
185
+ end
186
+ end
187
+
188
+ ##
189
+ # Returns an enumerator for {#each_triple}.
190
+ #
191
+ # @return [Enumerator]
192
+ # @see #each_triple
193
+ def enum_triple
194
+ require_enumerator!
195
+ ::Enumerable::Enumerator.new(self, :each_triple)
196
+ end
197
+
198
+ alias_method :enum_triples, :enum_triple
199
+
200
+ ##
201
+ # Returns all RDF quads.
202
+ #
203
+ # @param [Hash{Symbol => Boolean}] options
204
+ # @return [Array<Array(Resource, URI, Value, Resource)>]
205
+ # @see #each_quad
206
+ # @see #enum_quad
207
+ def quads(options = {})
208
+ enum_statement.map(&:to_quad)
209
+ end
210
+
211
+ ##
212
+ # Returns `true` if `self` contains the given RDF quad.
213
+ #
214
+ # @param [Array(Resource, URI, Value, Resource)] quad
215
+ # @return [Boolean]
216
+ def has_quad?(quad)
217
+ enum_quad.include?(quad)
218
+ end
219
+
220
+ ##
221
+ # Iterates the given block for each RDF quad.
222
+ #
223
+ # If no block was given, returns an enumerator.
224
+ #
225
+ # @overload each_quad
226
+ # @yield [subject, predicate, object, context]
227
+ # @yieldparam [Resource] subject
228
+ # @yieldparam [URI] predicate
229
+ # @yieldparam [Value] object
230
+ # @yieldparam [Resource] context
231
+ # @return [void]
232
+ #
233
+ # @overload each_quad
234
+ # @return [Enumerator]
235
+ #
236
+ # @return [void]
237
+ # @see #enum_quad
238
+ def each_quad(&block)
239
+ if block_given?
240
+ each_statement do |statement|
241
+ block.call(*statement.to_quad)
242
+ end
243
+ else
244
+ enum_quad
245
+ end
246
+ end
247
+
248
+ ##
249
+ # Returns an enumerator for {#each_quad}.
250
+ #
251
+ # @return [Enumerator]
252
+ # @see #each_quad
253
+ def enum_quad
254
+ require_enumerator!
255
+ ::Enumerable::Enumerator.new(self, :each_quad)
256
+ end
257
+
258
+ alias_method :enum_quads, :enum_quad
259
+
260
+ ##
261
+ # Returns all unique RDF subjects.
262
+ #
263
+ # @param [Hash{Symbol => Boolean}] options
264
+ # @option options [Boolean] :unique (true)
265
+ # @return [Array<Resource>]
266
+ # @see #each_subject
267
+ # @see #enum_subject
268
+ def subjects(options = {})
269
+ if options[:unique] == false
270
+ enum_statement.map(&:subject)
271
+ else
272
+ enum_subject.to_a
273
+ end
274
+ end
275
+
276
+ ##
277
+ # Returns `true` if `self` contains the given RDF subject.
278
+ #
279
+ # @param [Resource] value
280
+ # @return [Boolean]
281
+ def has_subject?(value)
282
+ enum_subject.include?(value)
283
+ end
284
+
285
+ ##
286
+ # Iterates the given block for each unique RDF subject.
287
+ #
288
+ # If no block was given, returns an enumerator.
289
+ #
290
+ # @overload each_subject
291
+ # @yield [subject]
292
+ # @yieldparam [Resource] subject
293
+ # @return [void]
294
+ #
295
+ # @overload each_subject
296
+ # @return [Enumerator]
297
+ #
298
+ # @return [void]
299
+ # @see #enum_subject
300
+ def each_subject(&block)
301
+ if block_given?
302
+ values = {}
303
+ each_statement do |statement|
304
+ value = statement.subject
305
+ unless value.nil? || values.include?(value.to_s)
306
+ values[value.to_s] = true
307
+ block.call(value)
308
+ end
309
+ end
310
+ else
311
+ enum_subject
312
+ end
313
+ end
314
+
315
+ ##
316
+ # Returns an enumerator for {#each_subject}.
317
+ #
318
+ # @return [Enumerator]
319
+ # @see #each_subject
320
+ def enum_subject
321
+ require_enumerator!
322
+ ::Enumerable::Enumerator.new(self, :each_subject)
323
+ end
324
+
325
+ alias_method :enum_subjects, :enum_subject
326
+
327
+ ##
328
+ # Returns all unique RDF predicates.
329
+ #
330
+ # @param [Hash{Symbol => Boolean}] options
331
+ # @option options [Boolean] :unique (true)
332
+ # @return [Array<URI>]
333
+ # @see #each_predicate
334
+ # @see #enum_predicate
335
+ def predicates(options = {})
336
+ if options[:unique] == false
337
+ enum_statement.map(&:predicate)
338
+ else
339
+ enum_predicate.to_a
340
+ end
341
+ end
342
+
343
+ ##
344
+ # Returns `true` if `self` contains the given RDF predicate.
345
+ #
346
+ # @param [URI] value
347
+ # @return [Boolean]
348
+ def has_predicate?(value)
349
+ enum_predicate.include?(value)
350
+ end
351
+
352
+ ##
353
+ # Iterates the given block for each unique RDF predicate.
354
+ #
355
+ # If no block was given, returns an enumerator.
356
+ #
357
+ # @overload each_predicate
358
+ # @yield [predicate]
359
+ # @yieldparam [URI] predicate
360
+ # @return [void]
361
+ #
362
+ # @overload each_predicate
363
+ # @return [Enumerator]
364
+ #
365
+ # @return [void]
366
+ # @see #enum_predicate
367
+ def each_predicate(&block)
368
+ if block_given?
369
+ values = {}
370
+ each_statement do |statement|
371
+ value = statement.predicate
372
+ unless value.nil? || values.include?(value.to_s)
373
+ values[value.to_s] = true
374
+ block.call(value)
375
+ end
376
+ end
377
+ else
378
+ enum_predicate
379
+ end
380
+ end
381
+
382
+ ##
383
+ # Returns an enumerator for {#each_predicate}.
384
+ #
385
+ # @return [Enumerator]
386
+ # @see #each_predicate
387
+ def enum_predicate
388
+ require_enumerator!
389
+ ::Enumerable::Enumerator.new(self, :each_predicate)
390
+ end
391
+
392
+ alias_method :enum_predicates, :enum_predicate
393
+
394
+ ##
395
+ # Returns all unique RDF objects.
396
+ #
397
+ # @param [Hash{Symbol => Boolean}] options
398
+ # @option options [Boolean] :unique (true)
399
+ # @return [Array<Value>]
400
+ # @see #each_object
401
+ # @see #enum_object
402
+ def objects(options = {})
403
+ if options[:unique] == false
404
+ enum_statement.map(&:object)
405
+ else
406
+ enum_object.to_a
407
+ end
408
+ end
409
+
410
+ ##
411
+ # Returns `true` if `self` contains the given RDF object.
412
+ #
413
+ # @param [Value] value
414
+ # @return [Boolean]
415
+ def has_object?(value)
416
+ enum_object.include?(value)
417
+ end
418
+
419
+ ##
420
+ # Iterates the given block for each unique RDF object.
421
+ #
422
+ # If no block was given, returns an enumerator.
423
+ #
424
+ # @overload each_object
425
+ # @yield [object]
426
+ # @yieldparam [Value] object
427
+ # @return [void]
428
+ #
429
+ # @overload each_object
430
+ # @return [Enumerator]
431
+ #
432
+ # @return [void]
433
+ # @see #enum_object
434
+ def each_object(&block) # FIXME: deduplication
435
+ if block_given?
436
+ values = {}
437
+ each_statement do |statement|
438
+ value = statement.object
439
+ unless value.nil? || values.include?(value)
440
+ values[value] = true
441
+ block.call(value)
442
+ end
443
+ end
444
+ else
445
+ enum_object
446
+ end
447
+ end
448
+
449
+ ##
450
+ # Returns an enumerator for {#each_object}.
451
+ #
452
+ # @return [Enumerator]
453
+ # @see #each_object
454
+ def enum_object
455
+ require_enumerator!
456
+ ::Enumerable::Enumerator.new(self, :each_object)
457
+ end
458
+
459
+ alias_method :enum_objects, :enum_object
460
+
461
+ ##
462
+ # Returns all unique RDF contexts.
463
+ #
464
+ # @param [Hash{Symbol => Boolean}] options
465
+ # @option options [Boolean] :unique (true)
466
+ # @return [Array<Resource>]
467
+ # @see #each_context
468
+ # @see #enum_context
469
+ def contexts(options = {})
470
+ if options[:unique] == false
471
+ enum_statement.map(&:context)
472
+ else
473
+ enum_context.to_a
474
+ end
475
+ end
476
+
477
+ ##
478
+ # Returns `true` if `self` contains the given RDF context.
479
+ #
480
+ # @param [Resource] value
481
+ # @return [Boolean]
482
+ def has_context?(value)
483
+ enum_context.include?(value)
484
+ end
485
+
486
+ ##
487
+ # Iterates the given block for each unique RDF context.
488
+ #
489
+ # If no block was given, returns an enumerator.
490
+ #
491
+ # @overload each_context
492
+ # @yield [context]
493
+ # @yieldparam [Resource] context
494
+ # @return [void]
495
+ #
496
+ # @overload each_context
497
+ # @return [Enumerator]
498
+ #
499
+ # @return [void]
500
+ # @see #enum_context
501
+ def each_context(&block)
502
+ if block_given?
503
+ values = {}
504
+ each_statement do |statement|
505
+ value = statement.context
506
+ unless value.nil? || values.include?(value)
507
+ values[value] = true
508
+ block.call(value)
509
+ end
510
+ end
511
+ else
512
+ enum_context
513
+ end
514
+ end
515
+
516
+ ##
517
+ # Returns an enumerator for {#each_context}.
518
+ #
519
+ # @return [Enumerator]
520
+ # @see #each_context
521
+ def enum_context
522
+ require_enumerator!
523
+ ::Enumerable::Enumerator.new(self, :each_context)
524
+ end
525
+
526
+ alias_method :enum_contexts, :enum_context
527
+
528
+ ##
529
+ # Returns all RDF objects indexed by their subjects and predicates.
530
+ #
531
+ # The return value is a `Hash` instance that has the structure:
532
+ # `{subject => {predicate => [*objects]}}`.
533
+ #
534
+ # @return [Hash{Resource => Hash{URI => Array<Value>}}]
535
+ def to_hash
536
+ result = {}
537
+ each_statement do |statement|
538
+ next if statement.invalid? # skip any incomplete statements
539
+
540
+ result[statement.subject] ||= {}
541
+ values = (result[statement.subject][statement.predicate] ||= [])
542
+ values << statement.object unless values.include?(statement.object)
543
+ end
544
+ result
545
+ end
546
+
547
+ private
548
+
549
+ def require_enumerator! # @private
550
+ require 'enumerator' unless defined?(::Enumerable::Enumerator)
551
+ end
552
+
553
+ end
554
+ end