rdf 1.0.10.2 → 1.1.0.p0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/CREDITS +0 -2
- data/README +67 -20
- data/VERSION +1 -1
- data/etc/doap.nt +75 -75
- data/lib/rdf.rb +15 -64
- data/lib/rdf/format.rb +11 -20
- data/lib/rdf/mixin/countable.rb +4 -11
- data/lib/rdf/mixin/enumerable.rb +4 -8
- data/lib/rdf/mixin/mutable.rb +1 -4
- data/lib/rdf/mixin/queryable.rb +13 -60
- data/lib/rdf/model/graph.rb +46 -22
- data/lib/rdf/model/list.rb +27 -102
- data/lib/rdf/model/literal.rb +48 -100
- data/lib/rdf/model/literal/date.rb +1 -1
- data/lib/rdf/model/literal/datetime.rb +1 -35
- data/lib/rdf/model/literal/decimal.rb +0 -30
- data/lib/rdf/model/literal/double.rb +6 -14
- data/lib/rdf/model/literal/integer.rb +3 -11
- data/lib/rdf/model/literal/numeric.rb +0 -40
- data/lib/rdf/model/literal/time.rb +4 -3
- data/lib/rdf/model/node.rb +1 -3
- data/lib/rdf/model/statement.rb +7 -47
- data/lib/rdf/model/term.rb +9 -0
- data/lib/rdf/model/uri.rb +28 -68
- data/lib/rdf/model/value.rb +1 -31
- data/lib/rdf/nquads.rb +4 -7
- data/lib/rdf/ntriples.rb +2 -2
- data/lib/rdf/ntriples/format.rb +1 -2
- data/lib/rdf/ntriples/reader.rb +15 -68
- data/lib/rdf/ntriples/writer.rb +13 -53
- data/lib/rdf/query.rb +1 -8
- data/lib/rdf/query/pattern.rb +25 -7
- data/lib/rdf/query/solution.rb +3 -19
- data/lib/rdf/query/solutions.rb +4 -22
- data/lib/rdf/query/variable.rb +1 -3
- data/lib/rdf/reader.rb +8 -22
- data/lib/rdf/repository.rb +23 -5
- data/lib/rdf/transaction.rb +19 -8
- data/lib/rdf/util/aliasing.rb +3 -13
- data/lib/rdf/util/cache.rb +2 -3
- data/lib/rdf/util/file.rb +5 -15
- data/lib/rdf/vocab.rb +19 -20
- data/lib/rdf/writer.rb +5 -44
- metadata +12 -27
- data/lib/rdf/vocab/schema.rb +0 -652
data/lib/rdf/format.rb
CHANGED
@@ -13,18 +13,18 @@ module RDF
|
|
13
13
|
# RDF::Format.for("etc/doap.nt")
|
14
14
|
# RDF::Format.for(:file_name => "etc/doap.nt")
|
15
15
|
# RDF::Format.for(:file_extension => "nt")
|
16
|
-
# RDF::Format.for(:content_type => "
|
16
|
+
# RDF::Format.for(:content_type => "text/plain")
|
17
17
|
#
|
18
18
|
# @example Obtaining serialization format MIME types
|
19
|
-
# RDF::Format.content_types #=> {"
|
19
|
+
# RDF::Format.content_types #=> {"text/plain" => [RDF::NTriples::Format]}
|
20
20
|
#
|
21
21
|
# @example Obtaining serialization format file extension mappings
|
22
22
|
# RDF::Format.file_extensions #=> {:nt => [RDF::NTriples::Format]}
|
23
23
|
#
|
24
24
|
# @example Defining a new RDF serialization format class
|
25
25
|
# class RDF::NTriples::Format < RDF::Format
|
26
|
-
# content_type '
|
27
|
-
# content_encoding '
|
26
|
+
# content_type 'text/plain', :extension => :nt
|
27
|
+
# content_encoding 'ascii'
|
28
28
|
#
|
29
29
|
# reader RDF::NTriples::Reader
|
30
30
|
# writer RDF::NTriples::Writer
|
@@ -142,14 +142,12 @@ module RDF
|
|
142
142
|
|
143
143
|
# If we have a sample, use that for format detection
|
144
144
|
if sample = (options[:sample] if options.is_a?(Hash)) || (yield if block_given?)
|
145
|
-
sample = sample.dup.to_s
|
146
|
-
sample.force_encoding(Encoding::US_ASCII) if sample.respond_to?(:force_encoding)
|
147
145
|
# Given a sample, perform format detection across the appropriate formats, choosing
|
148
146
|
# the first that matches
|
149
147
|
format ||= @@subclasses
|
150
148
|
|
151
149
|
# Return first format that has a positive detection
|
152
|
-
format.detect {|f| f.detect(sample)} || format.first
|
150
|
+
format.detect {|f| f.detect(sample.to_s)} || format.first
|
153
151
|
elsif format.is_a?(Array)
|
154
152
|
# Otherwise, just return the first matching format
|
155
153
|
format.first
|
@@ -251,7 +249,7 @@ module RDF
|
|
251
249
|
#
|
252
250
|
# @example
|
253
251
|
#
|
254
|
-
# RDF::NTriples::Format.name => "
|
252
|
+
# RDF::NTriples::Format.name => "NTriples"
|
255
253
|
#
|
256
254
|
# @return [Symbol]
|
257
255
|
def self.name
|
@@ -357,7 +355,7 @@ module RDF
|
|
357
355
|
# match cannot be unambigiously found otherwise.
|
358
356
|
#
|
359
357
|
# @example
|
360
|
-
# RDF::NTriples::Format.detect("<a> <b> <c> .")
|
358
|
+
# RDF::NTriples::Format.detect("<a> <b> <c> .") => true
|
361
359
|
#
|
362
360
|
# @param [String] sample Beginning several bytes (~ 1K) of input.
|
363
361
|
# @return [Boolean]
|
@@ -403,21 +401,14 @@ module RDF
|
|
403
401
|
|ct, cl| (cl.include?(self) && ct != @@content_type[self]) ? ct : nil }].flatten.compact
|
404
402
|
else
|
405
403
|
@@content_type[self] = type
|
406
|
-
@@content_types[type] ||= []
|
407
|
-
@@content_types[type] << self unless @@content_types[type].include?(self)
|
404
|
+
(@@content_types[type] ||= []) << self
|
408
405
|
|
409
406
|
if extensions = (options[:extension] || options[:extensions])
|
410
|
-
extensions =
|
411
|
-
extensions.each
|
412
|
-
@@file_extensions[ext] ||= []
|
413
|
-
@@file_extensions[ext] << self unless @@file_extensions[ext].include?(self)
|
414
|
-
end
|
407
|
+
extensions = [extensions].flatten.map(&:to_sym)
|
408
|
+
extensions.each { |ext| (@@file_extensions[ext] ||= []) << self }
|
415
409
|
end
|
416
410
|
if aliases = (options[:alias] || options[:aliases])
|
417
|
-
aliases =
|
418
|
-
@@content_types[a] ||= []
|
419
|
-
@@content_types[a] << self unless @@content_types[a].include?(self)
|
420
|
-
end
|
411
|
+
aliases = [aliases].flatten.each { |a| (@@content_types[a] ||= []) << self }
|
421
412
|
end
|
422
413
|
end
|
423
414
|
end
|
data/lib/rdf/mixin/countable.rb
CHANGED
@@ -9,8 +9,9 @@ module RDF
|
|
9
9
|
#
|
10
10
|
# @return [Boolean]
|
11
11
|
def empty?
|
12
|
-
|
13
|
-
|
12
|
+
empty = true
|
13
|
+
each { empty = false; break }
|
14
|
+
empty
|
14
15
|
end
|
15
16
|
|
16
17
|
##
|
@@ -31,16 +32,8 @@ module RDF
|
|
31
32
|
# @see Object#enum_for
|
32
33
|
def enum_for(method = :each, *args)
|
33
34
|
# Ensure that enumerators support the `#empty?` and `#count` methods:
|
34
|
-
|
35
|
-
Countable::Enumerator.new do |yielder|
|
36
|
-
this.send(method, *args) {|y| yielder << y}
|
37
|
-
end
|
35
|
+
super.extend(RDF::Countable)
|
38
36
|
end
|
39
37
|
alias_method :to_enum, :enum_for
|
40
|
-
|
41
|
-
# Extends Enumerator with {Countable}, which is used by {Countable#enum_for}
|
42
|
-
class Enumerator < ::Enumerator
|
43
|
-
include Countable
|
44
|
-
end
|
45
38
|
end # Countable
|
46
39
|
end # RDF
|
data/lib/rdf/mixin/enumerable.rb
CHANGED
@@ -17,10 +17,10 @@ module RDF
|
|
17
17
|
# enumerable.has_quad?([subject, predicate, object, context])
|
18
18
|
#
|
19
19
|
# @example Checking whether a specific value exists
|
20
|
-
# enumerable.has_subject?(RDF::URI("http://
|
20
|
+
# enumerable.has_subject?(RDF::URI("http://rdf.rubyforge.org/"))
|
21
21
|
# enumerable.has_predicate?(RDF::DC.creator)
|
22
|
-
# enumerable.has_object?(RDF::Literal("
|
23
|
-
# enumerable.has_context?(RDF::URI("http://
|
22
|
+
# enumerable.has_object?(RDF::Literal("Hello!", :language => :en))
|
23
|
+
# enumerable.has_context?(RDF::URI("http://rubyforge.org/"))
|
24
24
|
#
|
25
25
|
# @example Enumerating all statements
|
26
26
|
# enumerable.each_statement do |statement|
|
@@ -162,11 +162,7 @@ module RDF
|
|
162
162
|
# @return [Enumerator]
|
163
163
|
# @see #each_statement
|
164
164
|
def enum_statement
|
165
|
-
|
166
|
-
this = self
|
167
|
-
Queryable::Enumerator.new do |yielder|
|
168
|
-
this.send(:each_statement) {|y| yielder << y}
|
169
|
-
end
|
165
|
+
enum_for(:each_statement).extend(RDF::Queryable, RDF::Enumerable)
|
170
166
|
end
|
171
167
|
alias_method :enum_statements, :enum_statement
|
172
168
|
|
data/lib/rdf/mixin/mutable.rb
CHANGED
@@ -106,9 +106,6 @@ module RDF
|
|
106
106
|
|
107
107
|
##
|
108
108
|
# Deletes RDF statements from `self`.
|
109
|
-
# If any statement contains a {Query::Variable}, it is
|
110
|
-
# considered to be a pattern, and used to query
|
111
|
-
# self to find matching statements to delete.
|
112
109
|
#
|
113
110
|
# @param [Enumerable<RDF::Statement>] statements
|
114
111
|
# @raise [TypeError] if `self` is immutable
|
@@ -121,7 +118,7 @@ module RDF
|
|
121
118
|
when value.respond_to?(:each_statement)
|
122
119
|
delete_statements(value)
|
123
120
|
nil
|
124
|
-
when (statement = Statement.from(value)).
|
121
|
+
when (statement = Statement.from(value)).valid?
|
125
122
|
statement
|
126
123
|
else
|
127
124
|
delete_statements(query(value))
|
data/lib/rdf/mixin/queryable.rb
CHANGED
@@ -17,29 +17,18 @@ module RDF
|
|
17
17
|
# This method delegates to the protected {RDF::Queryable#query_pattern} method for the
|
18
18
|
# actual lower-level query pattern matching implementation.
|
19
19
|
#
|
20
|
-
# @example
|
20
|
+
# @example
|
21
21
|
# queryable.query([nil, RDF::DOAP.developer, nil])
|
22
|
-
# queryable.query(:predicate => RDF::DOAP.developer)
|
23
|
-
# puts statement.inspect
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# @example Querying for solutions from a BGP
|
27
|
-
# query = RDF::Query.new {pattern [:s, :p, :o]}
|
28
|
-
# queryable.query(query) do |solution|
|
29
|
-
# puts solution.inspect
|
30
|
-
# end
|
22
|
+
# queryable.query(:predicate => RDF::DOAP.developer)
|
31
23
|
#
|
32
24
|
# @param [RDF::Query, RDF::Statement, Array(RDF::Term), Hash] pattern
|
33
|
-
# @param [Hash{Symbol => Object}] options ({})
|
34
|
-
# Any other options passed to {#query_pattern} or {#query_execute}
|
35
25
|
# @yield [statement]
|
36
26
|
# each matching statement
|
37
|
-
# @yieldparam [RDF::Statement
|
38
|
-
# Statement or Solution
|
27
|
+
# @yieldparam [RDF::Statement] statement
|
39
28
|
# @yieldreturn [void] ignored
|
40
29
|
# @return [Enumerator]
|
41
30
|
# @see RDF::Queryable#query_pattern
|
42
|
-
def query(pattern,
|
31
|
+
def query(pattern, &block)
|
43
32
|
raise TypeError, "#{self} is not readable" if respond_to?(:readable?) && !readable?
|
44
33
|
|
45
34
|
case pattern
|
@@ -47,11 +36,7 @@ module RDF
|
|
47
36
|
when Query
|
48
37
|
if block_given?
|
49
38
|
before_query(pattern) if respond_to?(:before_query)
|
50
|
-
|
51
|
-
query_execute(pattern, &block)
|
52
|
-
else
|
53
|
-
query_execute(pattern, options, &block)
|
54
|
-
end
|
39
|
+
query_execute(pattern, &block)
|
55
40
|
after_query(pattern) if respond_to?(:after_query)
|
56
41
|
end
|
57
42
|
enum_for(:query_execute, pattern)
|
@@ -78,16 +63,14 @@ module RDF
|
|
78
63
|
|
79
64
|
# Otherwise, we delegate to `#query_pattern`:
|
80
65
|
else # pattern.variable?
|
81
|
-
if block_given?
|
82
|
-
if self.method(:query_pattern).arity == 1
|
83
|
-
query_pattern(pattern, &block)
|
84
|
-
else
|
85
|
-
query_pattern(pattern, options, &block)
|
86
|
-
end
|
87
|
-
end
|
66
|
+
query_pattern(pattern, &block) if block_given?
|
88
67
|
enum_for(:query_pattern, pattern)
|
89
68
|
end
|
90
69
|
after_query(pattern) if block_given? && respond_to?(:after_query)
|
70
|
+
enum.extend(RDF::Queryable, RDF::Enumerable, RDF::Countable)
|
71
|
+
def enum.to_a
|
72
|
+
super.extend(RDF::Queryable, RDF::Enumerable, RDF::Countable)
|
73
|
+
end
|
91
74
|
enum
|
92
75
|
end
|
93
76
|
end
|
@@ -102,8 +85,6 @@ module RDF
|
|
102
85
|
#
|
103
86
|
# @param [RDF::Query] query
|
104
87
|
# the query to execute
|
105
|
-
# @param [Hash{Symbol => Object}] options ({})
|
106
|
-
# Any other options passed to `query.execute`
|
107
88
|
# @yield [solution]
|
108
89
|
# @yieldparam [RDF::Query::Solution] solution
|
109
90
|
# @yieldreturn [void] ignored
|
@@ -111,12 +92,12 @@ module RDF
|
|
111
92
|
# @see RDF::Queryable#query
|
112
93
|
# @see RDF::Query#execute
|
113
94
|
# @since 0.3.0
|
114
|
-
def query_execute(query,
|
95
|
+
def query_execute(query, &block)
|
115
96
|
# By default, we let RDF.rb's built-in `RDF::Query#execute` handle BGP
|
116
97
|
# query execution by breaking down the query into its constituent
|
117
98
|
# triple patterns and invoking `RDF::Query::Pattern#execute` on each
|
118
99
|
# pattern.
|
119
|
-
query.execute(self
|
100
|
+
query.execute(self).each(&block)
|
120
101
|
end
|
121
102
|
protected :query_execute
|
122
103
|
|
@@ -130,8 +111,6 @@ module RDF
|
|
130
111
|
#
|
131
112
|
# @param [RDF::Query::Pattern] pattern
|
132
113
|
# the query pattern to match
|
133
|
-
# @param [Hash{Symbol => Object}] options ({})
|
134
|
-
# Any other options
|
135
114
|
# @yield [statement]
|
136
115
|
# @yieldparam [RDF::Statement] statement
|
137
116
|
# @yieldreturn [void] ignored
|
@@ -139,7 +118,7 @@ module RDF
|
|
139
118
|
# @see RDF::Queryable#query
|
140
119
|
# @see RDF::Query::Pattern#execute
|
141
120
|
# @since 0.2.0
|
142
|
-
def query_pattern(pattern,
|
121
|
+
def query_pattern(pattern, &block)
|
143
122
|
# By default, we let Ruby's built-in `Enumerable#grep` handle the
|
144
123
|
# matching of statements by iterating over all statements and calling
|
145
124
|
# `RDF::Query::Pattern#===` on each statement.
|
@@ -286,31 +265,5 @@ module RDF
|
|
286
265
|
def first_value(pattern = nil)
|
287
266
|
(literal = first_literal(pattern)) ? literal.value : nil
|
288
267
|
end
|
289
|
-
|
290
|
-
##
|
291
|
-
# @private
|
292
|
-
# @param [Symbol, #to_sym] method
|
293
|
-
# @return [Enumerator]
|
294
|
-
# @see Object#enum_for
|
295
|
-
def enum_for(method = :each, *args)
|
296
|
-
# Ensure that enumerators are, themselves, queryable
|
297
|
-
this = self
|
298
|
-
Queryable::Enumerator.new do |yielder|
|
299
|
-
this.send(method, *args) {|y| yielder << y}
|
300
|
-
end
|
301
|
-
end
|
302
|
-
alias_method :to_enum, :enum_for
|
303
|
-
|
304
|
-
|
305
|
-
# Extends Enumerator with {Queryable} and {Enumerable}, which is used by {Enumerable#each_statement} and {Queryable#enum_for}
|
306
|
-
class Enumerator < ::Enumerator
|
307
|
-
include Queryable
|
308
|
-
include Enumerable
|
309
|
-
|
310
|
-
# Make sure returned arrays are also queryable
|
311
|
-
def to_a
|
312
|
-
return super.to_a.extend(RDF::Queryable, RDF::Enumerable)
|
313
|
-
end
|
314
|
-
end
|
315
268
|
end # Queryable
|
316
269
|
end # RDF
|
data/lib/rdf/model/graph.rb
CHANGED
@@ -2,26 +2,31 @@ module RDF
|
|
2
2
|
##
|
3
3
|
# An RDF graph.
|
4
4
|
#
|
5
|
-
#
|
6
|
-
#
|
5
|
+
# An {RDF::Graph} contains a unique set of {RDF::Statement}. It is
|
6
|
+
# based on an underlying data object, which may be specified when the
|
7
|
+
# graph is initialized, and will default to a {RDF::Repository} without
|
8
|
+
# support for contexts otherwise.
|
7
9
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
+
# Note that in RDF 1.1, graphs are not named, but are associated with
|
11
|
+
# a name in the context of a Dataset, as a pair of <name, graph>.
|
12
|
+
# This class allows a name to be associated with a graph when it is
|
13
|
+
# a projection of an underlying {RDF::Repository} supporting contexts.
|
10
14
|
#
|
11
|
-
# @example
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# graph = RDF::Graph.new("http://www.bbc.co.uk/programmes/b0081dq5.rdf")
|
15
|
-
# graph.load!
|
15
|
+
# @example Creating an empty graph
|
16
|
+
# graph = Graph.new
|
16
17
|
#
|
17
|
-
# @example Loading graph data from a URL
|
18
|
+
# @example Loading graph data from a URL
|
18
19
|
# require 'rdf/rdfxml' # for RDF/XML support
|
19
20
|
#
|
20
21
|
# graph = RDF::Graph.load("http://www.bbc.co.uk/programmes/b0081dq5.rdf")
|
21
22
|
#
|
23
|
+
# @example Accessing a specific named graph within a {RDF::Repository}
|
24
|
+
# require 'rdf/trig' # for TriG support
|
25
|
+
#
|
26
|
+
# repository = RDF::Repository.load("https://raw.github.com/ruby-rdf/rdf-trig/master/etc/doap.trig")
|
27
|
+
# graph = RDF::Graph.new(:data => repository, :context => RDF::URI("http://greggkellogg.net/foaf#me"))
|
22
28
|
class Graph
|
23
|
-
include RDF::
|
24
|
-
|
29
|
+
include RDF::Value
|
25
30
|
include RDF::Countable
|
26
31
|
include RDF::Durable
|
27
32
|
include RDF::Enumerable
|
@@ -39,8 +44,7 @@ module RDF
|
|
39
44
|
# Name of this graph, if it is part of an {RDF::Repository}
|
40
45
|
# @!attribute [rw] context
|
41
46
|
# @return [RDF::Resource]
|
42
|
-
# @
|
43
|
-
# {RDF::Enumerable} supporting contexts will have a context.
|
47
|
+
# @since 1.1.0
|
44
48
|
attr_accessor :context
|
45
49
|
|
46
50
|
alias_method :name, :context
|
@@ -64,8 +68,8 @@ module RDF
|
|
64
68
|
# @return [Graph]
|
65
69
|
# @since 0.1.7
|
66
70
|
def self.load(url, options = {}, &block)
|
67
|
-
self.new(
|
68
|
-
graph.load
|
71
|
+
self.new(options) do |graph|
|
72
|
+
graph.load(url, options)
|
69
73
|
|
70
74
|
if block_given?
|
71
75
|
case block.arity
|
@@ -79,18 +83,24 @@ module RDF
|
|
79
83
|
##
|
80
84
|
# @overload initialize(context, options)
|
81
85
|
# @param [RDF::Resource] context
|
82
|
-
# The context
|
86
|
+
# The context from the associated {RDF::Queryable} associated
|
87
|
+
# with this graph as provided with the `:data` option
|
88
|
+
# (only for {RDF::Queryable} instances supporting
|
89
|
+
# named contexts).
|
83
90
|
# @param [Hash{Symbol => Object}] options
|
91
|
+
# @option options [RDF::Queryable] :data (RDF::Repository.new)
|
92
|
+
# Storage behind this graph.
|
93
|
+
# @raise [ArgumentError] if a `data` does not support contexts.
|
84
94
|
# @note contexts are only useful when used as a projection
|
85
95
|
# on a `:data` which supports contexts. Otherwise, there is no
|
86
96
|
# such thing as a named graph in RDF 1.1, a repository may have
|
87
97
|
# graphs which are named, but the name is not a property of the graph.
|
88
98
|
# @overload initialize(options)
|
89
99
|
# @param [Hash{Symbol => Object}] options
|
100
|
+
# @option options [RDF::Queryable] :data (RDF::Repository.new)
|
101
|
+
# Storage behind this graph.
|
90
102
|
# @yield [graph]
|
91
103
|
# @yieldparam [Graph]
|
92
|
-
# @note Currently, context makes this a named garph;
|
93
|
-
# in the next release it will not
|
94
104
|
def initialize(*args, &block)
|
95
105
|
context = args.shift unless args.first.is_a?(Hash)
|
96
106
|
options = args.first || {}
|
@@ -101,7 +111,10 @@ module RDF
|
|
101
111
|
end
|
102
112
|
|
103
113
|
@options = options.dup
|
104
|
-
@data = @options.delete(:data) || RDF::Repository.new
|
114
|
+
@data = @options.delete(:data) || RDF::Repository.new(:with_context => false)
|
115
|
+
|
116
|
+
raise ArgumentError, "Can't apply context unless initialized with `data` supporting contexts" if
|
117
|
+
@context && !@data.supports?(:context)
|
105
118
|
|
106
119
|
if block_given?
|
107
120
|
case block.arity
|
@@ -112,12 +125,14 @@ module RDF
|
|
112
125
|
end
|
113
126
|
|
114
127
|
##
|
128
|
+
# (re)loads the graph from the specified location, or from the location associated with the graph context, if any
|
115
129
|
# @return [void]
|
116
|
-
# @
|
130
|
+
# @see RDF::Mutable#load
|
117
131
|
def load!(*args)
|
118
132
|
case
|
119
133
|
when args.empty?
|
120
|
-
|
134
|
+
raise ArgumentError, "Can't reload graph with no context" unless context.is_a?(RDF::URI)
|
135
|
+
load(context.to_s, {:base_uri => context}.merge(@options))
|
121
136
|
else super
|
122
137
|
end
|
123
138
|
end
|
@@ -181,6 +196,15 @@ module RDF
|
|
181
196
|
named? ? context.to_s : "default"
|
182
197
|
end
|
183
198
|
|
199
|
+
##
|
200
|
+
# Returns `true` if this graph contains no RDF statements.
|
201
|
+
#
|
202
|
+
# @return [Boolean]
|
203
|
+
# @see RDF::Enumerable#empty?
|
204
|
+
def empty?
|
205
|
+
!@data.has_context?(context || false)
|
206
|
+
end
|
207
|
+
|
184
208
|
##
|
185
209
|
# Returns `true` if this graph has an anonymous context, `false` otherwise.
|
186
210
|
#
|
data/lib/rdf/model/list.rb
CHANGED
@@ -8,7 +8,8 @@ module RDF
|
|
8
8
|
# @since 0.2.3
|
9
9
|
class RDF::List
|
10
10
|
include RDF::Enumerable
|
11
|
-
include RDF::
|
11
|
+
include RDF::Value
|
12
|
+
include Comparable
|
12
13
|
|
13
14
|
##
|
14
15
|
# Constructs a new list from the given `values`.
|
@@ -38,12 +39,10 @@ module RDF
|
|
38
39
|
# @yield [list]
|
39
40
|
# @yieldparam [RDF::List] list
|
40
41
|
def initialize(subject = nil, graph = nil, values = nil, &block)
|
41
|
-
@subject = subject || RDF.
|
42
|
+
@subject = subject || RDF::Node.new
|
42
43
|
@graph = graph || RDF::Graph.new
|
43
44
|
|
44
|
-
unless values.
|
45
|
-
values.reverse_each {|value| self.unshift(value)}
|
46
|
-
end
|
45
|
+
values.each { |value| self << value } unless values.nil? || values.empty?
|
47
46
|
|
48
47
|
if block_given?
|
49
48
|
case block.arity
|
@@ -61,9 +60,10 @@ module RDF
|
|
61
60
|
##
|
62
61
|
# Validate the list ensuring that
|
63
62
|
# * rdf:rest values are all BNodes are nil
|
64
|
-
# *
|
65
|
-
#
|
66
|
-
#
|
63
|
+
# * each subject has exactly one value for `rdf:first` and
|
64
|
+
# `rdf:rest`.
|
65
|
+
# * The value of `rdf:rest` must be either a BNode or `rdf:nil`.
|
66
|
+
# * All other properties are ignored.
|
67
67
|
# @return [Boolean]
|
68
68
|
def valid?
|
69
69
|
li = subject
|
@@ -71,19 +71,13 @@ module RDF
|
|
71
71
|
rest = nil
|
72
72
|
firsts = rests = 0
|
73
73
|
@graph.query(:subject => li) do |st|
|
74
|
-
return false unless st.subject.node?
|
75
74
|
case st.predicate
|
76
|
-
when RDF.type
|
77
|
-
# Be tollerant about rdf:type entries, as some OWL vocabularies use it excessively
|
78
75
|
when RDF.first
|
79
76
|
firsts += 1
|
80
77
|
when RDF.rest
|
81
78
|
rest = st.object
|
82
79
|
return false unless rest.node? || rest == RDF.nil
|
83
80
|
rests += 1
|
84
|
-
else
|
85
|
-
# First node may have other properties
|
86
|
-
return false unless li == subject
|
87
81
|
end
|
88
82
|
end
|
89
83
|
return false unless firsts == 1 && rests == 1
|
@@ -199,7 +193,7 @@ module RDF
|
|
199
193
|
# Returns the element at `index`.
|
200
194
|
#
|
201
195
|
# @example
|
202
|
-
# RDF::List[1, 2, 3][0] #=>
|
196
|
+
# RDF::List[1, 2, 3][0] #=> 1
|
203
197
|
#
|
204
198
|
# @param [Integer] index
|
205
199
|
# @return [RDF::Term]
|
@@ -208,71 +202,6 @@ module RDF
|
|
208
202
|
at(index)
|
209
203
|
end
|
210
204
|
|
211
|
-
##
|
212
|
-
# Appends an element to the head of this list. Existing references are not updated, as the list subject changes as a side-effect.
|
213
|
-
#
|
214
|
-
# @example
|
215
|
-
# RDF::List[].unshift(1).unshift(2).unshift(3) #=> RDF::List[3, 2, 1]
|
216
|
-
#
|
217
|
-
# @param [RDF::Term] value
|
218
|
-
# @return [RDF::List]
|
219
|
-
# @see http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-unshift
|
220
|
-
#
|
221
|
-
def unshift(value)
|
222
|
-
value = case value
|
223
|
-
when nil then RDF.nil
|
224
|
-
when RDF::Value then value
|
225
|
-
when Array then RDF::List.new(nil, graph, value)
|
226
|
-
else value
|
227
|
-
end
|
228
|
-
|
229
|
-
new_subject, old_subject = RDF::Node.new, subject
|
230
|
-
|
231
|
-
graph.insert([new_subject, RDF.type, RDF.List])
|
232
|
-
graph.insert([new_subject, RDF.first, value.is_a?(RDF::List) ? value.subject : value])
|
233
|
-
graph.insert([new_subject, RDF.rest, old_subject])
|
234
|
-
|
235
|
-
@subject = new_subject
|
236
|
-
|
237
|
-
return self
|
238
|
-
end
|
239
|
-
|
240
|
-
##
|
241
|
-
# Removes and returns the element at the head of this list.
|
242
|
-
#
|
243
|
-
# @example
|
244
|
-
# RDF::List[1,2,3].shift #=> 1
|
245
|
-
#
|
246
|
-
# @return [RDF::Term]
|
247
|
-
# @see http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-shift
|
248
|
-
def shift
|
249
|
-
return nil if empty?
|
250
|
-
|
251
|
-
value = first
|
252
|
-
old_subject, new_subject = subject, rest_subject
|
253
|
-
graph.delete([old_subject, RDF.type, RDF.List])
|
254
|
-
graph.delete([old_subject, RDF.first, value])
|
255
|
-
graph.delete([old_subject, RDF.rest, new_subject])
|
256
|
-
|
257
|
-
@subject = new_subject
|
258
|
-
return value
|
259
|
-
end
|
260
|
-
|
261
|
-
##
|
262
|
-
# Empties this list
|
263
|
-
#
|
264
|
-
# @example
|
265
|
-
# RDF::List[1, 2, 2, 3].clear #=> RDF::List[]
|
266
|
-
#
|
267
|
-
# @return [RDF::List]
|
268
|
-
# @see http://ruby-doc.org/core-1.9.3/classes/Array.html#method-i-clear
|
269
|
-
def clear
|
270
|
-
until empty?
|
271
|
-
shift
|
272
|
-
end
|
273
|
-
return self
|
274
|
-
end
|
275
|
-
|
276
205
|
##
|
277
206
|
# Appends an element to the tail of this list.
|
278
207
|
#
|
@@ -291,14 +220,13 @@ module RDF
|
|
291
220
|
end
|
292
221
|
|
293
222
|
if empty?
|
294
|
-
|
223
|
+
new_subject = subject
|
295
224
|
else
|
296
225
|
old_subject, new_subject = last_subject, RDF::Node.new
|
297
226
|
graph.delete([old_subject, RDF.rest, RDF.nil])
|
298
227
|
graph.insert([old_subject, RDF.rest, new_subject])
|
299
228
|
end
|
300
229
|
|
301
|
-
graph.insert([new_subject, RDF.type, RDF.List])
|
302
230
|
graph.insert([new_subject, RDF.first, value.is_a?(RDF::List) ? value.subject : value])
|
303
231
|
graph.insert([new_subject, RDF.rest, RDF.nil])
|
304
232
|
|
@@ -367,12 +295,10 @@ module RDF
|
|
367
295
|
end
|
368
296
|
|
369
297
|
##
|
370
|
-
# Returns
|
298
|
+
# Returns the element at `index`.
|
371
299
|
#
|
372
300
|
# @example
|
373
|
-
#
|
374
|
-
# RDF::List[1, 2, 3].slice(0, 2) #=> RDF::List[1, 2],
|
375
|
-
# RDF::List[1, 2, 3].slice(0..2) #=> RDF::List[1, 2, 3]
|
301
|
+
# RDF::List[1, 2, 3].at(0) #=> 1
|
376
302
|
#
|
377
303
|
# @return [RDF::Term]
|
378
304
|
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000462
|
@@ -401,10 +327,10 @@ module RDF
|
|
401
327
|
protected :slice_with_range
|
402
328
|
|
403
329
|
##
|
404
|
-
# Returns element at `index
|
330
|
+
# Returns the element at `index`.
|
405
331
|
#
|
406
332
|
# @example
|
407
|
-
# RDF::List[1, 2, 3].fetch(0) #=>
|
333
|
+
# RDF::List[1, 2, 3].fetch(0) #=> 1
|
408
334
|
# RDF::List[1, 2, 3].fetch(4) #=> IndexError
|
409
335
|
# RDF::List[1, 2, 3].fetch(4, nil) #=> nil
|
410
336
|
# RDF::List[1, 2, 3].fetch(4) { |n| n*n } #=> 16
|
@@ -428,7 +354,6 @@ module RDF
|
|
428
354
|
#
|
429
355
|
# @example
|
430
356
|
# RDF::List[1, 2, 3].at(0) #=> 1
|
431
|
-
# RDF::List[1, 2, 3].at(4) #=> nil
|
432
357
|
#
|
433
358
|
# @return [RDF::Term]
|
434
359
|
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000419
|
@@ -445,7 +370,7 @@ module RDF
|
|
445
370
|
# Returns the first element in this list.
|
446
371
|
#
|
447
372
|
# @example
|
448
|
-
# RDF::List[*(1..10)].first #=>
|
373
|
+
# RDF::List[*(1..10)].first #=> 1
|
449
374
|
#
|
450
375
|
# @return [RDF::Term]
|
451
376
|
def first
|
@@ -456,7 +381,7 @@ module RDF
|
|
456
381
|
# Returns the second element in this list.
|
457
382
|
#
|
458
383
|
# @example
|
459
|
-
# RDF::List[*(1..10)].second #=>
|
384
|
+
# RDF::List[*(1..10)].second #=> 2
|
460
385
|
#
|
461
386
|
# @return [RDF::Term]
|
462
387
|
def second
|
@@ -467,7 +392,7 @@ module RDF
|
|
467
392
|
# Returns the third element in this list.
|
468
393
|
#
|
469
394
|
# @example
|
470
|
-
# RDF::List[*(1..10)].third #=>
|
395
|
+
# RDF::List[*(1..10)].third #=> 3
|
471
396
|
#
|
472
397
|
# @return [RDF::Term]
|
473
398
|
def third
|
@@ -478,7 +403,7 @@ module RDF
|
|
478
403
|
# Returns the fourth element in this list.
|
479
404
|
#
|
480
405
|
# @example
|
481
|
-
# RDF::List[*(1..10)].fourth #=>
|
406
|
+
# RDF::List[*(1..10)].fourth #=> 4
|
482
407
|
#
|
483
408
|
# @return [RDF::Term]
|
484
409
|
def fourth
|
@@ -489,7 +414,7 @@ module RDF
|
|
489
414
|
# Returns the fifth element in this list.
|
490
415
|
#
|
491
416
|
# @example
|
492
|
-
# RDF::List[*(1..10)].fifth #=>
|
417
|
+
# RDF::List[*(1..10)].fifth #=> 5
|
493
418
|
#
|
494
419
|
# @return [RDF::Term]
|
495
420
|
def fifth
|
@@ -500,7 +425,7 @@ module RDF
|
|
500
425
|
# Returns the sixth element in this list.
|
501
426
|
#
|
502
427
|
# @example
|
503
|
-
# RDF::List[*(1..10)].sixth #=>
|
428
|
+
# RDF::List[*(1..10)].sixth #=> 6
|
504
429
|
#
|
505
430
|
# @return [RDF::Term]
|
506
431
|
def sixth
|
@@ -511,7 +436,7 @@ module RDF
|
|
511
436
|
# Returns the seventh element in this list.
|
512
437
|
#
|
513
438
|
# @example
|
514
|
-
# RDF::List[*(1..10)].seventh #=>
|
439
|
+
# RDF::List[*(1..10)].seventh #=> 7
|
515
440
|
#
|
516
441
|
# @return [RDF::Term]
|
517
442
|
def seventh
|
@@ -522,7 +447,7 @@ module RDF
|
|
522
447
|
# Returns the eighth element in this list.
|
523
448
|
#
|
524
449
|
# @example
|
525
|
-
# RDF::List[*(1..10)].eighth #=>
|
450
|
+
# RDF::List[*(1..10)].eighth #=> 8
|
526
451
|
#
|
527
452
|
# @return [RDF::Term]
|
528
453
|
def eighth
|
@@ -533,7 +458,7 @@ module RDF
|
|
533
458
|
# Returns the ninth element in this list.
|
534
459
|
#
|
535
460
|
# @example
|
536
|
-
# RDF::List[*(1..10)].ninth #=>
|
461
|
+
# RDF::List[*(1..10)].ninth #=> 9
|
537
462
|
#
|
538
463
|
# @return [RDF::Term]
|
539
464
|
def ninth
|
@@ -544,7 +469,7 @@ module RDF
|
|
544
469
|
# Returns the tenth element in this list.
|
545
470
|
#
|
546
471
|
# @example
|
547
|
-
# RDF::List[*(1..10)].tenth #=>
|
472
|
+
# RDF::List[*(1..10)].tenth #=> 10
|
548
473
|
#
|
549
474
|
# @return [RDF::Term]
|
550
475
|
def tenth
|
@@ -555,7 +480,7 @@ module RDF
|
|
555
480
|
# Returns the last element in this list.
|
556
481
|
#
|
557
482
|
# @example
|
558
|
-
# RDF::List[
|
483
|
+
# RDF::List[1, 2, 3].last #=> 3
|
559
484
|
#
|
560
485
|
# @return [RDF::Term]
|
561
486
|
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000422
|
@@ -747,7 +672,7 @@ module RDF
|
|
747
672
|
#
|
748
673
|
# @example
|
749
674
|
# RDF::List[].to_a #=> []
|
750
|
-
# RDF::List[1, 2, 3].to_a #=> [
|
675
|
+
# RDF::List[1, 2, 3].to_a #=> [1, 2, 3]
|
751
676
|
#
|
752
677
|
# @return [Array]
|
753
678
|
def to_a
|
@@ -758,7 +683,7 @@ module RDF
|
|
758
683
|
# Returns the elements in this list as a set.
|
759
684
|
#
|
760
685
|
# @example
|
761
|
-
# RDF::List[1, 2, 3].to_set #=> Set[
|
686
|
+
# RDF::List[1, 2, 3].to_set #=> Set[1, 2, 3]
|
762
687
|
#
|
763
688
|
# @return [Set]
|
764
689
|
def to_set
|