rdf 1.0.3 → 1.0.4

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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YjI3YmJmYTZkOGMwMTc2M2VkYTY4YWFiZGQ2YWRlN2E0NmQ5YzIxOQ==
5
+ data.tar.gz: !binary |-
6
+ NmU0NTA4ODAwNTNkNzJmMWQ1M2U3M2IyODFiNjJkYjRhM2ZiNjM2ZA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NTM5MDM3NjEzMWZhZTYwMjg1MGZjOGY5OTY4ODMyNDIxNjZjOTJiYTdiZDhk
10
+ YzAyZGUyYzllYjU1ZWZkMjM4NzEzMWU4NzViNGI0ZGI4YWMzZWEyZWJlZTkz
11
+ MzRjOTgyMzE1ZWZjN2UyYTIwZGM5ZWI4ZDRjYjhmODg0MGY5ZGM=
12
+ data.tar.gz: !binary |-
13
+ ZTA3MDBiYzUyYTBlYjJlNTk1Njg5NDYwNzI5ZTY3MGIzNjU5NmEyMjlkZTVl
14
+ MzQ4MTFjMmQyZTE1NDgwODc0ZTk4YThlYzRmYjJmOTBhYjdlYzQxOGFiZTg1
15
+ Y2MxOTQ4NDBhNzg3YzNmYjIwNWIwNjUyYTNiYzE3MzEzZTAwMzI=
data/README CHANGED
@@ -115,6 +115,23 @@ A specific sub-type of Writer can also be invoked directly:
115
115
 
116
116
  graph.dump(:nquads)
117
117
 
118
+ ## Reader/Writer convenience methods
119
+ {RDF::Enumerable} implements `to_{format}` for each available instance of {RDF::Reader}.
120
+ For example, if `rdf/turtle` is loaded, this allows the following:
121
+
122
+ graph = RDF::Graph.new << [:hello, RDF::DC.title, "Hello, world!"]
123
+ graph.to_ttl
124
+
125
+ Similarly, {RDF::Mutable} implements `from_{format}` for each available instance
126
+ of {RDF::Writer}. For example:
127
+
128
+ graph = RDF::Graph.new
129
+ graph.from_ttl("[ a <http://www.w3.org/1999/02/22-rdf-syntax-ns#Resource>]")
130
+
131
+ Note that no prefixes are loaded automatically, however they can be provided as arguments:
132
+
133
+ graph.from_ttl("[ a rdf:Resource]", :prefixes => {:rdf => RDF.to_uri})
134
+
118
135
  ### Querying RDF data using basic graph patterns (BGPs)
119
136
 
120
137
  require 'rdf/ntriples'
@@ -317,6 +334,7 @@ follows:
317
334
 
318
335
  * Do your best to adhere to the existing coding conventions and idioms.
319
336
  * Don't use hard tabs, and don't leave trailing whitespace on any line.
337
+ Before committing, run `git diff --check` to make sure of this.
320
338
  * Do document every method you add using [YARD][] annotations. Read the
321
339
  [tutorial][YARD-GS] or just look at the existing code for examples.
322
340
  * Don't touch the `.gemspec` or `VERSION` files. If you need to change them,
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.3
1
+ 1.0.4
@@ -181,29 +181,55 @@ module RDF
181
181
  end
182
182
 
183
183
  ##
184
- # Returns the set of format symbols for loaded RDF::Reader subclasses.
184
+ # Returns the set of format symbols for available RDF::Reader subclasses.
185
185
  #
186
186
  # @example
187
187
  #
188
- # formats = RDF::Format.reader_symbols
189
- # format = RDF::Format.for(formats.first)
188
+ # symbols = RDF::Format.reader_symbols
189
+ # format = RDF::Format.for(symbols.first)
190
190
  #
191
191
  # @return [Array<Symbol>]
192
192
  def self.reader_symbols
193
- RDF::Format.each.to_a.map(&:reader).compact.map(&:to_sym).uniq
193
+ @@readers.keys.compact.map(&:to_sym).uniq
194
194
  end
195
195
 
196
196
  ##
197
- # Returns the set of format symbols for loaded RDF::Writer subclasses.
197
+ # Returns the set of content types for available RDF::Reader subclasses.
198
198
  #
199
199
  # @example
200
200
  #
201
- # formats = RDF::Format.writer_symbols
202
- # format = RDF::Format.for(formats.first)
201
+ # content_types = RDF::Format.reader_types
202
+ # format = RDF::Format.for(:content_type => content_types.first)
203
+ #
204
+ # @return [Array<String>]
205
+ def self.reader_types
206
+ reader_symbols.map {|s| RDF::Format.for(s).content_type}.flatten.uniq
207
+ end
208
+
209
+ ##
210
+ # Returns the set of format symbols for available RDF::Writer subclasses.
211
+ #
212
+ # @example
213
+ #
214
+ # symbols = RDF::Format.writer_symbols
215
+ # format = RDF::Format.for(symbols.first)
203
216
  #
204
217
  # @return [Array<Symbol>]
205
218
  def self.writer_symbols
206
- RDF::Format.each.to_a.map(&:writer).compact.map(&:to_sym).uniq
219
+ @@writers.keys.compact.map(&:to_sym).uniq
220
+ end
221
+
222
+ ##
223
+ # Returns the set of content types for available RDF::Writer subclasses.
224
+ #
225
+ # @example
226
+ #
227
+ # content_types = RDF::Format.writer_types
228
+ # format = RDF::Format.for(:content_type => content_types.first)
229
+ #
230
+ # @return [Array<String>]
231
+ def self.writer_types
232
+ writer_symbols.map {|s| RDF::Format.for(s).content_type}.flatten.uniq
207
233
  end
208
234
 
209
235
  ##
@@ -492,7 +492,7 @@ module RDF
492
492
  alias_method :enum_objects, :enum_object
493
493
 
494
494
  ##
495
- # Returns all unique RDF contexts.
495
+ # Returns all unique RDF contexts, other than the default context.
496
496
  #
497
497
  # @param [Hash{Symbol => Boolean}] options
498
498
  # @option options [Boolean] :unique (true)
@@ -510,14 +510,15 @@ module RDF
510
510
  ##
511
511
  # Returns `true` if `self` contains the given RDF context.
512
512
  #
513
- # @param [RDF::Resource] value
513
+ # @param [RDF::Resource, false] value
514
+ # Use value `false` to query for the default context
514
515
  # @return [Boolean]
515
516
  def has_context?(value)
516
517
  enum_context.include?(value)
517
518
  end
518
519
 
519
520
  ##
520
- # Iterates the given block for each unique RDF context.
521
+ # Iterates the given block for each unique RDF context, other than the default context.
521
522
  #
522
523
  # If no block was given, returns an enumerator.
523
524
  #
@@ -664,5 +665,21 @@ module RDF
664
665
  raise RDF::WriterError, "No writer found using #{args.inspect}" unless writer
665
666
  writer.dump(self, nil, options)
666
667
  end
668
+
669
+ ##
670
+ # @overload #to_writer
671
+ # Implements #to_writer for each available instance of {RDF::Writer},
672
+ # based on the writer symbol.
673
+ #
674
+ # @return [String]
675
+ # @see {RDF::Writer.sym}
676
+ def method_missing(meth, *args)
677
+ writer = RDF::Writer.for(meth.to_s[3..-1].to_sym) if meth.to_s[0,3] == "to_"
678
+ if writer
679
+ writer.buffer(:standard_prefixes => true) {|w| w << self}
680
+ else
681
+ super
682
+ end
683
+ end
667
684
  end # Enumerable
668
685
  end # RDF
@@ -152,6 +152,23 @@ module RDF
152
152
 
153
153
  alias_method :clear!, :clear
154
154
 
155
+ ##
156
+ # @overload #from_reader
157
+ # Implements #from_reader for each available instance of {RDF::Reader},
158
+ # based on the reader symbol.
159
+ #
160
+ # Arguments are passed to Reader.new.
161
+ #
162
+ # @return [String]
163
+ # @see {RDF::Reader.sym}
164
+ def method_missing(meth, *args)
165
+ reader = RDF::Reader.for(meth.to_s[5..-1].to_sym) if meth.to_s[0,5] == "from_"
166
+ if reader
167
+ self << reader.new(*args)
168
+ else
169
+ super
170
+ end
171
+ end
155
172
  protected
156
173
 
157
174
  ##
@@ -184,8 +201,5 @@ module RDF
184
201
  def delete_statement(statement)
185
202
  raise NotImplementedError.new("#{self.class}#delete_statement")
186
203
  end
187
-
188
- protected :delete_statements
189
- protected :delete_statement
190
204
  end
191
205
  end
@@ -147,10 +147,14 @@ module RDF
147
147
  query(pattern) do |statement|
148
148
  return statement
149
149
  end
150
- return nil
150
+ elsif respond_to?(:each_statement)
151
+ each_statement do |statement|
152
+ return statement
153
+ end
151
154
  else
152
- super()
155
+ return super()
153
156
  end
157
+ nil
154
158
  end
155
159
 
156
160
  ##
@@ -31,15 +31,24 @@ module RDF
31
31
  ##
32
32
  # Returns the options passed to this graph when it was constructed.
33
33
  #
34
+ # @!attribute [r] options
34
35
  # @return [Hash{Symbol => Object}]
35
36
  attr_reader :options
36
37
 
37
38
  ##
39
+ # Name of this graph, if it is part of an {RDF::Repository}
40
+ # @!attribute [rw] context
38
41
  # @return [RDF::Resource]
39
- # @deprecated In the next release, graphs will have no name
42
+ # @note In the next release, only projections from an
43
+ # {RDF::Enumerable} supporting contexts will have a context.
40
44
  attr_accessor :context
41
45
 
46
+ alias_method :name, :context
47
+ alias_method :name=, :context=
48
+
42
49
  ##
50
+ # {RDF::Queryable} backing this graph.
51
+ # @!attribute [rw] data
43
52
  # @return [RDF::Queryable]
44
53
  attr_accessor :data
45
54
 
@@ -72,9 +81,10 @@ module RDF
72
81
  # @param [RDF::Resource] context
73
82
  # The context only provides a context for loading relative documents
74
83
  # @param [Hash{Symbol => Object}] options
75
- # @deprecated Graph context will be removed in the next release.
76
- # This is because context relates to a Named Graph in RDF 1.1
77
- # and a default graph has no context/name.
84
+ # @note contexts are only useful when used as a projection
85
+ # on a `:data` which supports contexts. Otherwise, there is no
86
+ # such thing as a named graph in RDF 1.1, a repository may have
87
+ # graphs which are named, but the name is not a property of the graph.
78
88
  # @overload initialize(options)
79
89
  # @param [Hash{Symbol => Object}] options
80
90
  # @yield [graph]
@@ -139,12 +149,12 @@ module RDF
139
149
  end
140
150
 
141
151
  ##
142
- # Returns `false` to indicate that this graph is not durable
152
+ # A graph is durable if it's underlying data model is durable
143
153
  #
144
154
  # @return [Boolean]
145
155
  # @see RDF::Durable#durable?
146
156
  def durable?
147
- false
157
+ @data.durable?
148
158
  end
149
159
 
150
160
  ##
@@ -156,10 +166,9 @@ module RDF
156
166
  end
157
167
 
158
168
  ##
159
- # Returns the URI representation of this graph.
169
+ # Returns the {RDF::Resource} representation of this graph.
160
170
  #
161
- # @return [RDF::URI]
162
- # @note The next release, graphs will not be named, this will return nil
171
+ # @return [RDF::Resource]
163
172
  def to_uri
164
173
  context
165
174
  end
@@ -169,7 +178,7 @@ module RDF
169
178
  #
170
179
  # @return [String]
171
180
  def to_s
172
- named? ? context.to_s : "<>"
181
+ named? ? context.to_s : "default"
173
182
  end
174
183
 
175
184
  ##
@@ -178,7 +187,7 @@ module RDF
178
187
  # @return [Boolean]
179
188
  # @see RDF::Enumerable#empty?
180
189
  def empty?
181
- @data.empty?
190
+ !@data.has_context?(context || false)
182
191
  end
183
192
 
184
193
  ##
@@ -196,7 +205,7 @@ module RDF
196
205
  # @return [Integer]
197
206
  # @see RDF::Enumerable#count
198
207
  def count
199
- @data.query(:context => context).count
208
+ @data.query(:context => context || false).count
200
209
  end
201
210
 
202
211
  ##
@@ -207,7 +216,7 @@ module RDF
207
216
  # @see RDF::Enumerable#has_statement?
208
217
  def has_statement?(statement)
209
218
  statement = statement.dup
210
- statement.context = context # TODO: going away
219
+ statement.context = context
211
220
  @data.has_statement?(statement)
212
221
  end
213
222
 
@@ -219,7 +228,27 @@ module RDF
219
228
  # @return [Enumerator]
220
229
  # @see RDF::Enumerable#each_statement
221
230
  def each(&block)
222
- @data.query(:context => context).each(&block)
231
+ if @data.respond_to?(:query)
232
+ @data.query(:context => context || false, &block)
233
+ elsif @data.respond_to?(:each)
234
+ @data.each(&block)
235
+ else
236
+ @data.to_a.each(&block)
237
+ end
238
+ end
239
+
240
+ ##
241
+ # Graph equivalence based on the contents of each graph being _exactly_
242
+ # the same. To determine if the have the same _meaning_, consider
243
+ # [rdf-isomorphic](http://rubygems.org/gems/rdf-isomorphic).
244
+ #
245
+ # @param [RDF::Graph] other
246
+ # @return [Boolean]
247
+ # @see http://rubygems.org/gems/rdf-isomorphic
248
+ def ==(other)
249
+ other.is_a?(RDF::Graph) &&
250
+ context == other.context &&
251
+ statements.to_a == other.statements.to_a
223
252
  end
224
253
 
225
254
  ##
@@ -227,7 +256,7 @@ module RDF
227
256
  # @see RDF::Queryable#query
228
257
  def query_pattern(pattern, &block)
229
258
  pattern = pattern.dup
230
- pattern.context = context
259
+ pattern.context = context || false
231
260
  @data.query(pattern, &block)
232
261
  end
233
262
 
@@ -253,7 +282,7 @@ module RDF
253
282
  # @private
254
283
  # @see RDF::Mutable#clear
255
284
  def clear_statements
256
- @data.delete(:context => context)
285
+ @data.delete(:context => context || false)
257
286
  end
258
287
 
259
288
  protected :query_pattern
@@ -343,6 +343,17 @@ module RDF
343
343
  self
344
344
  end
345
345
 
346
+ ##
347
+ # Returns the base representation of this URI.
348
+ #
349
+ # @return [Sring]
350
+ def to_base
351
+ text = %("#{escape(value)}")
352
+ text << "@#{language}" if has_language?
353
+ text << "^^#{datatype.to_base}" if has_datatype?
354
+ text
355
+ end
356
+
346
357
  ##
347
358
  # Returns the value as a string.
348
359
  #
@@ -137,6 +137,14 @@ module RDF
137
137
  end
138
138
  alias_method :===, :==
139
139
 
140
+ ##
141
+ # Returns the base representation of this URI.
142
+ #
143
+ # @return [Sring]
144
+ def to_base
145
+ to_s
146
+ end
147
+
140
148
  ##
141
149
  # Returns a string representation of this blank node.
142
150
  #
@@ -57,6 +57,7 @@ module RDF
57
57
  # @option options [RDF::URI] :predicate (nil)
58
58
  # @option options [RDF::Term] :object (nil)
59
59
  # @option options [RDF::Resource] :context (nil)
60
+ # Note, in RDF 1.1, a context MUST be an IRI.
60
61
  #
61
62
  # @overload initialize(subject, predicate, object, options = {})
62
63
  # @param [RDF::Resource] subject
@@ -259,25 +260,9 @@ module RDF
259
260
  #
260
261
  # @return [String]
261
262
  def to_s
262
- StringIO.open do |buffer|
263
- buffer << case subject
264
- when RDF::Node then subject.to_s
265
- when RDF::URI then "<#{subject}>"
266
- else subject.inspect
267
- end
268
- buffer << " <#{predicate}> "
269
- buffer << case object
270
- when RDF::Literal then object.to_s
271
- when RDF::Node then object.to_s
272
- when RDF::URI then "<#{object}>"
273
- else object.inspect
274
- end
275
- buffer << case context
276
- when nil then " ."
277
- else " <#{context}> ."
278
- end
279
- buffer.string
280
- end
263
+ (context ? to_quad : to_triple).map do |term|
264
+ term.respond_to?(:to_base) ? term.to_base : term.inspect
265
+ end.join(" ") + " ."
281
266
  end
282
267
 
283
268
  ##
@@ -66,12 +66,36 @@ module RDF
66
66
  end
67
67
 
68
68
  ##
69
- # Returns `true` if this term is variable.
69
+ # Returns a base representation of `self`.
70
70
  #
71
- # @return [Boolean] `true` or `false`
72
- # @see #constant?
73
- def variable?
74
- false
71
+ # @return [RDF::Value]
72
+ def to_base
73
+ self
74
+ end
75
+
76
+ ##
77
+ # Returns `true` if `self` is a {RDF::Term}.
78
+ #
79
+ # @return [Boolean]
80
+ def term?
81
+ true
75
82
  end
83
+
84
+ protected
85
+ ##
86
+ # Escape a term using standard character escapes
87
+ #
88
+ # @param [String] string
89
+ # @return [String]
90
+ def escape(string)
91
+ string.gsub('\\', '\\\\').
92
+ gsub("\b", '\\b').
93
+ gsub("\f", '\\f').
94
+ gsub("\t", '\\t').
95
+ gsub("\n", '\\n').
96
+ gsub("\r", '\\r').
97
+ gsub('"', '\\"')
98
+ end
99
+
76
100
  end # Term
77
101
  end # RDF
@@ -19,6 +19,7 @@ module RDF
19
19
  # @example Getting the string representation of a URI
20
20
  # uri.to_s #=> "http://rdf.rubyforge.org/"
21
21
  #
22
+ # http://en.wikipedia.org/wiki/Internationalized_Resource_Identifier
22
23
  # @see http://en.wikipedia.org/wiki/Uniform_Resource_Identifier
23
24
  # @see http://www.ietf.org/rfc/rfc3986.txt
24
25
  # @see http://www.ietf.org/rfc/rfc3987.txt
@@ -41,54 +42,54 @@ module RDF
41
42
  [\\u{A0000}-\\u{AFFFD}]|[\\u{B0000}-\\u{BFFFD}]|[\\u{C0000}-\\u{CFFFD}]|
42
43
  [\\u{D0000}-\\u{DFFFD}]|[\\u{E0000}-\\u{EFFFD}]
43
44
  EOS
44
- IPRIVATE = Regexp.compile("[\\uE000-\\uF8FF]|[\\u{F0000}-\\u{FFFFD}]|[\\u100000-\\u10FFFD]")
45
+ IPRIVATE = Regexp.compile("[\\uE000-\\uF8FF]|[\\u{F0000}-\\u{FFFFD}]|[\\u100000-\\u10FFFD]").freeze
45
46
  end
46
47
 
47
- SCHEME = Regexp.compile("[A-za-z](?:[A-Za-z0-9+-\.])*")
48
- PORT = Regexp.compile("[0-9]*")
49
- IP_literal = Regexp.compile("\\[[0-9A-Fa-f:\\.]*\\]") # Simplified, no IPvFuture
50
- PCT_ENCODED = Regexp.compile("%[0-9A-Fa-f]{2}")
51
- GEN_DELIMS = Regexp.compile("[:/\\?\\#\\[\\]@]")
52
- SUB_DELIMS = Regexp.compile("[!\\$&'\\(\\)\\*\\+,;=]")
53
- RESERVED = Regexp.compile("(?:#{GEN_DELIMS}|#{SUB_DELIMS})")
54
- UNRESERVED = Regexp.compile("[A-Za-z0-9]|-|\\.|_|~")
48
+ SCHEME = Regexp.compile("[A-za-z](?:[A-Za-z0-9+-\.])*").freeze
49
+ PORT = Regexp.compile("[0-9]*").freeze
50
+ IP_literal = Regexp.compile("\\[[0-9A-Fa-f:\\.]*\\]").freeze # Simplified, no IPvFuture
51
+ PCT_ENCODED = Regexp.compile("%[0-9A-Fa-f]{2}").freeze
52
+ GEN_DELIMS = Regexp.compile("[:/\\?\\#\\[\\]@]").freeze
53
+ SUB_DELIMS = Regexp.compile("[!\\$&'\\(\\)\\*\\+,;=]").freeze
54
+ RESERVED = Regexp.compile("(?:#{GEN_DELIMS}|#{SUB_DELIMS})").freeze
55
+ UNRESERVED = Regexp.compile("[A-Za-z0-9]|-|\\.|_|~").freeze
55
56
 
56
57
  if RUBY_VERSION >= '1.9'
57
- IUNRESERVED = Regexp.compile("[A-Za-z0-9]|-|\\.|_|~|#{UCSCHAR}")
58
+ IUNRESERVED = Regexp.compile("[A-Za-z0-9]|-|\\.|_|~|#{UCSCHAR}").freeze
58
59
  else
59
- IUNRESERVED = Regexp.compile("[A-Za-z0-9]|-|\\.|_|~")
60
+ IUNRESERVED = Regexp.compile("[A-Za-z0-9]|-|\\.|_|~").freeze
60
61
  end
61
62
 
62
- IPCHAR = Regexp.compile("(?:#{IUNRESERVED}|#{PCT_ENCODED}|#{SUB_DELIMS}|:|@)")
63
+ IPCHAR = Regexp.compile("(?:#{IUNRESERVED}|#{PCT_ENCODED}|#{SUB_DELIMS}|:|@)").freeze
63
64
 
64
65
  if RUBY_VERSION >= '1.9'
65
- IQUERY = Regexp.compile("(?:#{IPCHAR}|#{IPRIVATE}|/|\\?)*")
66
+ IQUERY = Regexp.compile("(?:#{IPCHAR}|#{IPRIVATE}|/|\\?)*").freeze
66
67
  else
67
- IQUERY = Regexp.compile("(?:#{IPCHAR}|/|\\?)*")
68
+ IQUERY = Regexp.compile("(?:#{IPCHAR}|/|\\?)*").freeze
68
69
  end
69
70
 
70
- IFRAGMENT = Regexp.compile("(?:#{IPCHAR}|/|\\?)*")
71
+ IFRAGMENT = Regexp.compile("(?:#{IPCHAR}|/|\\?)*").freeze.freeze
71
72
 
72
- ISEGMENT = Regexp.compile("(?:#{IPCHAR})*")
73
- ISEGMENT_NZ = Regexp.compile("(?:#{IPCHAR})+")
74
- ISEGMENT_NZ_NC = Regexp.compile("(?:(?:#{IUNRESERVED})|(?:#{PCT_ENCODED})|(?:#{SUB_DELIMS})|@)+")
73
+ ISEGMENT = Regexp.compile("(?:#{IPCHAR})*").freeze
74
+ ISEGMENT_NZ = Regexp.compile("(?:#{IPCHAR})+").freeze
75
+ ISEGMENT_NZ_NC = Regexp.compile("(?:(?:#{IUNRESERVED})|(?:#{PCT_ENCODED})|(?:#{SUB_DELIMS})|@)+").freeze
75
76
 
76
- IPATH_ABEMPTY = Regexp.compile("(?:/#{ISEGMENT})*")
77
- IPATH_ABSOLUTE = Regexp.compile("/(?:(?:#{ISEGMENT_NZ})(/#{ISEGMENT})*)?")
78
- IPATH_NOSCHEME = Regexp.compile("(?:#{ISEGMENT_NZ_NC})(?:/#{ISEGMENT})*")
79
- IPATH_ROOTLESS = Regexp.compile("(?:#{ISEGMENT_NZ})(?:/#{ISEGMENT})*")
80
- IPATH_EMPTY = Regexp.compile("")
77
+ IPATH_ABEMPTY = Regexp.compile("(?:/#{ISEGMENT})*").freeze
78
+ IPATH_ABSOLUTE = Regexp.compile("/(?:(?:#{ISEGMENT_NZ})(/#{ISEGMENT})*)?").freeze
79
+ IPATH_NOSCHEME = Regexp.compile("(?:#{ISEGMENT_NZ_NC})(?:/#{ISEGMENT})*").freeze
80
+ IPATH_ROOTLESS = Regexp.compile("(?:#{ISEGMENT_NZ})(?:/#{ISEGMENT})*").freeze
81
+ IPATH_EMPTY = Regexp.compile("").freeze
81
82
 
82
- IREG_NAME = Regexp.compile("(?:(?:#{IUNRESERVED})|(?:#{PCT_ENCODED})|(?:#{SUB_DELIMS}))*")
83
- IHOST = Regexp.compile("(?:#{IP_literal})|(?:#{IREG_NAME})")
84
- IUSERINFO = Regexp.compile("(?:(?:#{IUNRESERVED})|(?:#{PCT_ENCODED})|(?:#{SUB_DELIMS})|:)*")
85
- IAUTHORITY = Regexp.compile("(?:#{IUSERINFO}@)?#{IHOST}(?::#{PORT})?")
83
+ IREG_NAME = Regexp.compile("(?:(?:#{IUNRESERVED})|(?:#{PCT_ENCODED})|(?:#{SUB_DELIMS}))*").freeze
84
+ IHOST = Regexp.compile("(?:#{IP_literal})|(?:#{IREG_NAME})").freeze
85
+ IUSERINFO = Regexp.compile("(?:(?:#{IUNRESERVED})|(?:#{PCT_ENCODED})|(?:#{SUB_DELIMS})|:)*").freeze
86
+ IAUTHORITY = Regexp.compile("(?:#{IUSERINFO}@)?#{IHOST}(?::#{PORT})?").freeze
86
87
 
87
- IRELATIVE_PART = Regexp.compile("(?:(?://#{IAUTHORITY}(?:#{IPATH_ABEMPTY}))|(?:#{IPATH_ABSOLUTE})|(?:#{IPATH_NOSCHEME})|(?:#{IPATH_EMPTY}))")
88
- IRELATIVE_REF = Regexp.compile("^#{IRELATIVE_PART}(?:\\?#{IQUERY})?(?:\\##{IFRAGMENT})?$")
88
+ IRELATIVE_PART = Regexp.compile("(?:(?://#{IAUTHORITY}(?:#{IPATH_ABEMPTY}))|(?:#{IPATH_ABSOLUTE})|(?:#{IPATH_NOSCHEME})|(?:#{IPATH_EMPTY}))").freeze
89
+ IRELATIVE_REF = Regexp.compile("^#{IRELATIVE_PART}(?:\\?#{IQUERY})?(?:\\##{IFRAGMENT})?$").freeze
89
90
 
90
- IHIER_PART = Regexp.compile("(?:(?://#{IAUTHORITY}#{IPATH_ABEMPTY})|(?:#{IPATH_ABSOLUTE})|(?:#{IPATH_ROOTLESS})|(?:#{IPATH_EMPTY}))")
91
- IRI = Regexp.compile("^#{SCHEME}:(?:#{IHIER_PART})(?:\\?#{IQUERY})?(?:\\##{IFRAGMENT})?$")
91
+ IHIER_PART = Regexp.compile("(?:(?://#{IAUTHORITY}#{IPATH_ABEMPTY})|(?:#{IPATH_ABSOLUTE})|(?:#{IPATH_ROOTLESS})|(?:#{IPATH_EMPTY}))").freeze
92
+ IRI = Regexp.compile("^#{SCHEME}:(?:#{IHIER_PART})(?:\\?#{IQUERY})?(?:\\##{IFRAGMENT})?$").freeze
92
93
 
93
94
  ##
94
95
  # @return [RDF::Util::Cache]
@@ -148,14 +149,6 @@ module RDF
148
149
  end
149
150
  end
150
151
 
151
- ##
152
- # Returns `false`.
153
- #
154
- # @return [Boolean] `true` or `false`
155
- def anonymous?
156
- false
157
- end
158
-
159
152
  ##
160
153
  # Returns `true`.
161
154
  #
@@ -592,6 +585,14 @@ module RDF
592
585
  self
593
586
  end
594
587
 
588
+ ##
589
+ # Returns the base representation of this URI.
590
+ #
591
+ # @return [Sring]
592
+ def to_base
593
+ "<#{escape(@uri.to_s)}>"
594
+ end
595
+
595
596
  ##
596
597
  # Returns the string representation of this URI.
597
598
  #
@@ -641,4 +642,7 @@ module RDF
641
642
  end
642
643
  end
643
644
  end # URI
645
+
646
+ # RDF::IRI is a synonym for RDF::URI
647
+ IRI = URI
644
648
  end # RDF
@@ -4,7 +4,8 @@ module RDF
4
4
  #
5
5
  # This is the basis for the RDF.rb class hierarchy. Anything that can be a
6
6
  # term of {RDF::Statement RDF statements} should directly or indirectly
7
- # include this module.
7
+ # include this module, but it does not define classes that can be included
8
+ # within a {RDF::Statement}, for this see {RDF::Term}.
8
9
  #
9
10
  # @example Checking if a value is a resource (blank node or URI reference)
10
11
  # value.resource?
@@ -19,15 +20,16 @@ module RDF
19
20
  # @example Checking if a value is a literal
20
21
  # value.literal?
21
22
  #
22
- # @see RDF::Graph
23
23
  # @see RDF::Literal
24
24
  # @see RDF::Node
25
25
  # @see RDF::Resource
26
- # @see RDF::Statement
27
26
  # @see RDF::URI
27
+ # @see RDF::Graph
28
+ # @see RDF::List
29
+ # @see RDF::Statement
28
30
  module Value
29
31
  ##
30
- # Returns `true` if `self` is a graph.
32
+ # Returns `true` if `self` is a {RDF::Graph}.
31
33
  #
32
34
  # @return [Boolean]
33
35
  def graph?
@@ -35,23 +37,31 @@ module RDF
35
37
  end
36
38
 
37
39
  ##
38
- # Returns `true` if `self` is a literal.
40
+ # Returns `true` if `self` is a {RDF::Statement}.
39
41
  #
40
42
  # @return [Boolean]
41
- def literal?
43
+ def statement?
42
44
  false
43
45
  end
44
46
 
45
47
  ##
46
- # Returns `true` if `self` is a blank node.
48
+ # Returns `true` if `self` is a {RDF::List}.
47
49
  #
48
50
  # @return [Boolean]
49
- def node?
51
+ def list?
50
52
  false
51
53
  end
52
54
 
53
55
  ##
54
- # Returns `true` if `self` is a resource.
56
+ # Returns `true` if `self` is a {RDF::Term}.
57
+ #
58
+ # @return [Boolean]
59
+ def term?
60
+ false
61
+ end
62
+
63
+ ##
64
+ # Returns `true` if `self` is a {RDF::Resource}.
55
65
  #
56
66
  # @return [Boolean]
57
67
  def resource?
@@ -59,10 +69,18 @@ module RDF
59
69
  end
60
70
 
61
71
  ##
62
- # Returns `true` if `self` is a statement.
72
+ # Returns `true` if `self` is a {RDF::Literal}.
63
73
  #
64
74
  # @return [Boolean]
65
- def statement?
75
+ def literal?
76
+ false
77
+ end
78
+
79
+ ##
80
+ # Returns `true` if `self` is a {RDF::Node}.
81
+ #
82
+ # @return [Boolean]
83
+ def node?
66
84
  false
67
85
  end
68
86
 
@@ -77,7 +95,7 @@ module RDF
77
95
  end
78
96
 
79
97
  ##
80
- # Returns `true` if `self` is a URI reference.
98
+ # Returns `true` if `self` is a {RDF::URI}.
81
99
  #
82
100
  # @return [Boolean]
83
101
  def uri?
@@ -85,7 +103,7 @@ module RDF
85
103
  end
86
104
 
87
105
  ##
88
- # Returns `true` if `self` is a query variable.
106
+ # Returns `true` if `self` is a {RDF::Query::Variable}.
89
107
  #
90
108
  # @return [Boolean]
91
109
  # @since 0.1.7
@@ -93,6 +111,14 @@ module RDF
93
111
  false
94
112
  end
95
113
 
114
+ ##
115
+ # Is this an anonymous value?
116
+ #
117
+ # @return [Boolean] `true` or `false`
118
+ def anonymous?
119
+ false
120
+ end
121
+
96
122
  ##
97
123
  # Returns `true` if the value has a valid representation
98
124
  #
@@ -14,12 +14,13 @@ module RDF
14
14
  # RDF::Format.for("etc/doap.nq")
15
15
  # RDF::Format.for(:file_name => "etc/doap.nq")
16
16
  # RDF::Format.for(:file_extension => "nq")
17
+ # RDF::Format.for(:content_type => "application/n-quads")
17
18
  # RDF::Format.for(:content_type => "text/x-nquads")
18
19
  #
19
20
  # @see http://sw.deri.org/2008/07/n-quads/#mediatype
20
21
  # @since 0.4.0
21
22
  class Format < RDF::Format
22
- content_type 'text/x-nquads', :extension => :nq
23
+ content_type 'application/n-quads', :extension => :nq, :alias => ['text/x-nquads']
23
24
  content_encoding 'utf-8'
24
25
 
25
26
  reader { RDF::NQuads::Reader }
@@ -78,6 +79,9 @@ module RDF
78
79
  predicate = read_uriref(:intern => true) || fail_predicate
79
80
  object = read_uriref || read_node || read_literal || fail_object
80
81
  context = read_uriref || read_node || read_literal
82
+ if validate? && !read_eos
83
+ raise RDF::ReaderError, "expected end of statement in line #{lineno}: #{current_line.inspect}"
84
+ end
81
85
  return [subject, predicate, object, {:context => context}]
82
86
  end
83
87
  rescue RDF::ReaderError => e
@@ -28,20 +28,6 @@ module RDF::NTriples
28
28
  class Reader < RDF::Reader
29
29
  format RDF::NTriples::Format
30
30
 
31
- # @see http://www.w3.org/TR/rdf-testcases/#ntrip_grammar
32
- COMMENT = /^#\s*(.*)$/.freeze
33
- NODEID = /^_:([A-Za-z][A-Za-z0-9\-_]*)/.freeze
34
- URIREF = /^<([^>]+)>/.freeze
35
- LITERAL_PLAIN = /^"((?:\\"|[^"])*)"/.freeze
36
- LITERAL_WITH_LANGUAGE = /^"((?:\\"|[^"])*)"@([a-z]+[\-A-Za-z0-9]*)/.freeze
37
- LITERAL_WITH_DATATYPE = /^"((?:\\"|[^"])*)"\^\^<([^>]+)>/.freeze
38
- LANGUAGE_TAG = /^@([a-z]+[\-A-Za-z0-9]*)/.freeze
39
- DATATYPE_URI = /^\^\^<([^>]+)>/.freeze
40
- LITERAL = Regexp.union(LITERAL_WITH_LANGUAGE, LITERAL_WITH_DATATYPE, LITERAL_PLAIN).freeze
41
- SUBJECT = Regexp.union(URIREF, NODEID).freeze
42
- PREDICATE = Regexp.union(URIREF).freeze
43
- OBJECT = Regexp.union(URIREF, NODEID, LITERAL).freeze
44
-
45
31
  # @see http://www.w3.org/TR/rdf-testcases/#ntrip_strings
46
32
  ESCAPE_CHARS = ["\b", "\f", "\t", "\n", "\r", "\"", "\\"].freeze
47
33
  ESCAPE_CHAR4 = /\\u([0-9A-Fa-f]{4,4})/.freeze
@@ -51,6 +37,97 @@ module RDF::NTriples
51
37
  ESCAPE_SURROGATE1 = (0xD800..0xDBFF).freeze
52
38
  ESCAPE_SURROGATE2 = (0xDC00..0xDFFF).freeze
53
39
 
40
+
41
+ # Terminals from rdf-turtle.
42
+ #
43
+ # @see http://www.w3.org/TR/n-triples/
44
+ # @see http://www.w3.org/TR/turtle/
45
+ if RUBY_VERSION >= '1.9'
46
+ ##
47
+ # Unicode regular expressions for Ruby 1.9+ with the Oniguruma engine.
48
+ U_CHARS1 = Regexp.compile(<<-EOS.gsub(/\s+/, ''))
49
+ [\\u00C0-\\u00D6]|[\\u00D8-\\u00F6]|[\\u00F8-\\u02FF]|
50
+ [\\u0370-\\u037D]|[\\u037F-\\u1FFF]|[\\u200C-\\u200D]|
51
+ [\\u2070-\\u218F]|[\\u2C00-\\u2FEF]|[\\u3001-\\uD7FF]|
52
+ [\\uF900-\\uFDCF]|[\\uFDF0-\\uFFFD]|[\\u{10000}-\\u{EFFFF}]
53
+ EOS
54
+ U_CHARS2 = Regexp.compile("\\u00B7|[\\u0300-\\u036F]|[\\u203F-\\u2040]").freeze
55
+ IRI_RANGE = Regexp.compile("[[^<>\"{}|^`\\\\]&&[^\\x00-\\x20]]").freeze
56
+ else
57
+ ##
58
+ # UTF-8 regular expressions for Ruby 1.8.x.
59
+ U_CHARS1 = Regexp.compile(<<-EOS.gsub(/\s+/, ''))
60
+ \\xC3[\\x80-\\x96]| (?# [\\u00C0-\\u00D6]|)
61
+ \\xC3[\\x98-\\xB6]| (?# [\\u00D8-\\u00F6]|)
62
+ \\xC3[\\xB8-\\xBF]|[\\xC4-\\xCB][\\x80-\\xBF]| (?# [\\u00F8-\\u02FF]|)
63
+ \\xCD[\\xB0-\\xBD]| (?# [\\u0370-\\u037D]|)
64
+ \\xCD\\xBF|[\\xCE-\\xDF][\\x80-\\xBF]| (?# [\\u037F-\\u1FFF]|)
65
+ \\xE0[\\xA0-\\xBF][\\x80-\\xBF]| (?# ...)
66
+ \\xE1[\\x80-\\xBF][\\x80-\\xBF]| (?# ...)
67
+ \\xE2\\x80[\\x8C-\\x8D]| (?# [\\u200C-\\u200D]|)
68
+ \\xE2\\x81[\\xB0-\\xBF]| (?# [\\u2070-\\u218F]|)
69
+ \\xE2[\\x82-\\x85][\\x80-\\xBF]| (?# ...)
70
+ \\xE2\\x86[\\x80-\\x8F]| (?# ...)
71
+ \\xE2[\\xB0-\\xBE][\\x80-\\xBF]| (?# [\\u2C00-\\u2FEF]|)
72
+ \\xE2\\xBF[\\x80-\\xAF]| (?# ...)
73
+ \\xE3\\x80[\\x81-\\xBF]| (?# [\\u3001-\\uD7FF]|)
74
+ \\xE3[\\x81-\\xBF][\\x80-\\xBF]| (?# ...)
75
+ [\\xE4-\\xEC][\\x80-\\xBF][\\x80-\\xBF]| (?# ...)
76
+ \\xED[\\x80-\\x9F][\\x80-\\xBF]| (?# ...)
77
+ \\xEF[\\xA4-\\xB6][\\x80-\\xBF]| (?# [\\uF900-\\uFDCF]|)
78
+ \\xEF\\xB7[\\x80-\\x8F]| (?# ...)
79
+ \\xEF\\xB7[\\xB0-\\xBF]| (?# [\\uFDF0-\\uFFFD]|)
80
+ \\xEF[\\xB8-\\xBE][\\x80-\\xBF]| (?# ...)
81
+ \\xEF\\xBF[\\x80-\\xBD]| (?# ...)
82
+ \\xF0[\\x90-\\xBF][\\x80-\\xBF][\\x80-\\xBF]| (?# [\\u{10000}-\\u{EFFFF}])
83
+ [\\xF1-\\xF2][\\x80-\\xBF][\\x80-\\xBF][\\x80-\\xBF]|
84
+ \\xF3[\\x80-\\xAF][\\x80-\\xBF][\\x80-\\xBF] (?# ...)
85
+ EOS
86
+ U_CHARS2 = Regexp.compile(<<-EOS.gsub(/\s+/, ''))
87
+ \\xC2\\xB7| (?# \\u00B7|)
88
+ \\xCC[\\x80-\\xBF]|\\xCD[\\x80-\\xAF]| (?# [\\u0300-\\u036F]|)
89
+ \\xE2\\x80\\xBF|\\xE2\\x81\\x80 (?# [\\u203F-\\u2040])
90
+ EOS
91
+ IRI_RANGE = Regexp.compile(<<-EOS.gsub(/\s+/, ''))
92
+ \\x21| (?# ")
93
+ [\\x23-\\x3b]|\\x3d| (?# < & >)
94
+ [\\x3f-\\x5b]|\\x5d|\\x5f| (?# \ ^ `)
95
+ [\\x61-\\x7a]| (?# { } |)
96
+ [\\x7e-\\xff]
97
+ EOS
98
+ end
99
+
100
+ # 163s
101
+ PN_CHARS_BASE = /[A-Z]|[a-z]|#{U_CHARS1}/.freeze
102
+ # 164s
103
+ PN_CHARS_U = /_|#{PN_CHARS_BASE}/.freeze
104
+ # 166s
105
+ PN_CHARS = /-|[0-9]|#{PN_CHARS_U}|#{U_CHARS2}/.freeze
106
+ # 159s
107
+ ECHAR = /\\[tbnrf\\"']/.freeze
108
+ # 18
109
+ IRIREF = /<((?:#{IRI_RANGE}|#{ESCAPE_CHAR})*)>/.freeze
110
+ # 141s
111
+ BLANK_NODE_LABEL = /_:((?:[0-9]|#{PN_CHARS_U})(?:(?:#{PN_CHARS}|\.)*#{PN_CHARS})?)/.freeze
112
+ # 144s
113
+ LANGTAG = /@([a-zA-Z]+(?:-[a-zA-Z0-9]+)*)/.freeze
114
+ # 22
115
+ STRING_LITERAL_QUOTE = /"((?:[^\"\\\n\r]|#{ECHAR}|#{ESCAPE_CHAR})*)"/.freeze
116
+
117
+ # @see http://www.w3.org/TR/rdf-testcases/#ntrip_grammar
118
+ COMMENT = /^#\s*(.*)$/.freeze
119
+ NODEID = /^#{BLANK_NODE_LABEL}/.freeze
120
+ URIREF = /^#{IRIREF}/.freeze
121
+ LITERAL_PLAIN = /^#{STRING_LITERAL_QUOTE}/.freeze
122
+ LITERAL_WITH_LANGUAGE = /^#{STRING_LITERAL_QUOTE}#{LANGTAG}/.freeze
123
+ LITERAL_WITH_DATATYPE = /^#{STRING_LITERAL_QUOTE}\^\^#{IRIREF}/.freeze
124
+ DATATYPE_URI = /^\^\^#{IRIREF}/.freeze
125
+ LITERAL = Regexp.union(LITERAL_WITH_LANGUAGE, LITERAL_WITH_DATATYPE, LITERAL_PLAIN).freeze
126
+ SUBJECT = Regexp.union(URIREF, NODEID).freeze
127
+ PREDICATE = Regexp.union(URIREF).freeze
128
+ OBJECT = Regexp.union(URIREF, NODEID, LITERAL).freeze
129
+ END_OF_STATEMENT = /^\s*\.\s*$/.freeze
130
+
54
131
  ##
55
132
  # Reconstructs an RDF value from its serialized N-Triples
56
133
  # representation.
@@ -124,6 +201,7 @@ module RDF::NTriples
124
201
  # @see http://blog.grayproductions.net/articles/understanding_m17n
125
202
  # @see http://yehudakatz.com/2010/05/17/encodings-unabridged/
126
203
  def self.unescape(string)
204
+ string = string.to_s
127
205
  string = string.dup.force_encoding(Encoding::ASCII_8BIT) if string.respond_to?(:force_encoding)
128
206
 
129
207
  # Decode \t|\n|\r|\"|\\ character escapes:
@@ -135,8 +213,10 @@ module RDF::NTriples
135
213
  if ESCAPE_SURROGATE1.include?($1.hex) && ESCAPE_SURROGATE2.include?($2.hex)
136
214
  s = [$1, $2].pack('H*H*')
137
215
  s = s.respond_to?(:force_encoding) ?
138
- s.force_encoding(Encoding::UTF_16BE).encode!(Encoding::UTF_8) : # for Ruby 1.9+
139
- Iconv.conv('UTF-8', 'UTF-16BE', s) # for Ruby 1.8.x
216
+ # for Ruby 1.9+
217
+ s.force_encoding(Encoding::UTF_16BE).encode!(Encoding::UTF_8) :
218
+ # for Ruby 1.8.x
219
+ Iconv.conv('UTF-8', 'UTF-16BE', s)
140
220
  else
141
221
  s = [$1.hex].pack('U*') << '\u' << $2
142
222
  end
@@ -159,7 +239,7 @@ module RDF::NTriples
159
239
  def read_value
160
240
  begin
161
241
  read_statement
162
- rescue RDF::ReaderError => e
242
+ rescue RDF::ReaderError
163
243
  read_uriref || read_node || read_literal
164
244
  end
165
245
  end
@@ -177,6 +257,9 @@ module RDF::NTriples
177
257
  subject = read_uriref || read_node || fail_subject
178
258
  predicate = read_uriref(:intern => true) || fail_predicate
179
259
  object = read_uriref || read_node || read_literal || fail_object
260
+ if validate? && !read_eos
261
+ raise RDF::ReaderError, "expected end of statement in line #{lineno}: #{current_line.inspect}"
262
+ end
180
263
  return [subject, predicate, object]
181
264
  end
182
265
  rescue RDF::ReaderError => e
@@ -201,6 +284,7 @@ module RDF::NTriples
201
284
  uri_str = self.class.unescape(uri_str)
202
285
  uri = RDF::URI.send(intern? && options[:intern] ? :intern : :new, uri_str)
203
286
  uri.validate! if validate?
287
+ raise RDF::ReaderError, "uri not absolute" if validate? && !uri.absolute?
204
288
  uri.canonicalize! if canonicalize?
205
289
  uri
206
290
  end
@@ -210,7 +294,7 @@ module RDF::NTriples
210
294
  # @return [RDF::Node]
211
295
  # @see http://www.w3.org/TR/rdf-testcases/#ntrip_grammar (nodeID)
212
296
  def read_node
213
- if node_id = match(NODEID)
297
+ if node_id = match(NODEID)
214
298
  @nodes ||= {}
215
299
  @nodes[node_id] ||= RDF::Node.new(node_id)
216
300
  end
@@ -223,7 +307,7 @@ module RDF::NTriples
223
307
  if literal_str = match(LITERAL_PLAIN)
224
308
  literal_str = self.class.unescape(literal_str)
225
309
  literal = case
226
- when language = match(LANGUAGE_TAG)
310
+ when language = match(LANGTAG)
227
311
  RDF::Literal.new(literal_str, :language => language)
228
312
  when datatype = match(/^(\^\^)/) # FIXME
229
313
  RDF::Literal.new(literal_str, :datatype => read_uriref || fail_object)
@@ -235,5 +319,12 @@ module RDF::NTriples
235
319
  literal
236
320
  end
237
321
  end
322
+
323
+ ##
324
+ # @return [Boolean]
325
+ # @see http://www.w3.org/TR/rdf-testcases/#ntrip_grammar (triple)
326
+ def read_eos
327
+ match(END_OF_STATEMENT)
328
+ end
238
329
  end # Reader
239
330
  end # RDF::NTriples
@@ -209,7 +209,7 @@ module RDF::NTriples
209
209
  # @param [Hash{Symbol => Object}] options
210
210
  # @return [String]
211
211
  def format_node(node, options = {})
212
- "_:%s" % node.id
212
+ node.to_base
213
213
  end
214
214
 
215
215
  ##
@@ -219,7 +219,7 @@ module RDF::NTriples
219
219
  # @param [Hash{Symbol => Object}] options
220
220
  # @return [String]
221
221
  def format_uri(uri, options = {})
222
- "<%s>" % escaped(uri_for(uri))
222
+ uri.to_base
223
223
  end
224
224
 
225
225
  ##
@@ -231,6 +231,7 @@ module RDF::NTriples
231
231
  def format_literal(literal, options = {})
232
232
  case literal
233
233
  when RDF::Literal
234
+ # Note, escaping here is more robust than in Term
234
235
  text = quoted(escaped(literal.value))
235
236
  text << "@#{literal.language}" if literal.has_language?
236
237
  text << "^^<#{uri_for(literal.datatype)}>" if literal.has_datatype?
@@ -129,10 +129,12 @@ module RDF
129
129
  # @option options [RDF::Resource, RDF::Query::Variable, false] :context (nil)
130
130
  # Default context for matching against queryable.
131
131
  # Named queries either match against a specifically named
132
- # contexts if the name is an {RDF::Resource} or bound {RDF::Query::Variable}.
133
- # Names that are against unbound variables match either detault
134
- # or named contexts.
132
+ # graphs if the name is an {RDF::Resource} or bound {RDF::Query::Variable}.
133
+ # Names that are against unbound variables match either default
134
+ # or named graphs.
135
135
  # The name of `false` will only match against the default context.
136
+ # @option options [RDF::Resource, RDF::Query::Variable, false] :name (nil)
137
+ # Alias for `:context`.
136
138
  # @yield [query]
137
139
  # @yieldparam [RDF::Query] query
138
140
  # @yieldreturn [void] ignored
@@ -146,9 +148,11 @@ module RDF
146
148
  # @option options [RDF::Resource, RDF::Query::Variable, false] :context (nil)
147
149
  # Default context for matching against queryable.
148
150
  # Named queries either match against a specifically named
149
- # contexts if the name is an {RDF::Resource} or bound {RDF::Query::Variable}.
150
- # Names that are against unbound variables match either detault
151
- # or named contexts.
151
+ # graphs if the name is an {RDF::Resource} or bound {RDF::Query::Variable}.
152
+ # Names that are against unbound variables match either default
153
+ # or named graphs.
154
+ # @option options [RDF::Resource, RDF::Query::Variable, false] :name (nil)
155
+ # Alias for `:context`.
152
156
  # @yield [query]
153
157
  # @yieldparam [RDF::Query] query
154
158
  # @yieldreturn [void] ignored
@@ -157,7 +161,9 @@ module RDF
157
161
  patterns << @options if patterns.empty?
158
162
  @variables = {}
159
163
  @solutions = @options.delete(:solutions) || Solutions.new
160
- context = @options.delete(:context)
164
+ context = @options.fetch(:context, @options.fetch(:name, nil))
165
+ @options.delete(:context)
166
+ @options.delete(:name)
161
167
 
162
168
  @patterns = case patterns.first
163
169
  when Hash then compile_hash_patterns(HashPatternNormalizer.normalize!(patterns.first.dup, @options))
@@ -246,6 +252,8 @@ module RDF
246
252
  # @option options [RDF::Resource, RDF::Query::Variable, false] context (nil)
247
253
  # Specific context for matching against queryable;
248
254
  # overrides default context defined on query.
255
+ # @option options [RDF::Resource, RDF::Query::Variable, false] name (nil)
256
+ # Alias for `:context`.
249
257
  # @option options [Hash{Symbol => RDF::Term}] solutions
250
258
  # optional initial solutions for chained queries
251
259
  # @return [RDF::Query::Solutions]
@@ -264,7 +272,7 @@ module RDF
264
272
  @solutions = options[:solutions] || (Solutions.new << RDF::Query::Solution.new({}))
265
273
 
266
274
  patterns = @patterns
267
- context = options.fetch(:context, self.context)
275
+ context = options.fetch(:context, options.fetch(:name, self.context))
268
276
 
269
277
  # Add context to pattern, if necessary
270
278
  unless context.nil?
@@ -349,27 +357,34 @@ module RDF
349
357
  Query.new(self.patterns + other.patterns)
350
358
  end
351
359
 
352
- # Is this is a named query?
360
+ # Is this query scoped to a named graph?
353
361
  # @return [Boolean]
354
362
  def named?
355
363
  !!options[:context]
356
364
  end
357
365
 
358
- # Is this is an unamed query?
366
+ # Is this query scoped to the default graph?
367
+ # @return [Boolean]
368
+ def default?
369
+ options[:context] == false
370
+ end
371
+
372
+ # Is this query unscoped? This indicates that it can return results from
373
+ # either a named graph or the default graph.
359
374
  # @return [Boolean]
360
375
  def unnamed?
361
- !named?
376
+ options[:context].nil?
362
377
  end
363
378
 
364
- # Add name to query
365
- # @param [RDF::Value] value
366
- # @return [RDF::Value]
379
+ # Scope the query to named graphs matching value
380
+ # @param [RDF::IRI, RDF::Query::Variable] value
381
+ # @return [RDF::IRI, RDF::Query::Variable]
367
382
  def context=(value)
368
383
  options[:context] = value
369
384
  end
370
385
 
371
- # Name of this query, if any
372
- # @return [RDF::Value]
386
+ # Scope of this query, if any
387
+ # @return [RDF::IRI, RDF::Query::Variable]
373
388
  def context
374
389
  options[:context]
375
390
  end
@@ -22,9 +22,11 @@ class RDF::Query
22
22
  #
23
23
  class Solution
24
24
  # Undefine all superfluous instance methods:
25
- undef_method(*(instance_methods.map(&:to_sym) - [:__id__, :__send__, :__class__, :__eval__,
26
- :object_id, :dup, :instance_eval, :inspect, :to_s,
27
- :class, :is_a?, :respond_to?, :respond_to_missing?]))
25
+ undef_method(*instance_methods.
26
+ map(&:to_s).
27
+ select {|m| m =~ /^\w+$/}.
28
+ reject {|m| %w(object_id dup instance_eval inspect to_s class).include?(m) || m[0,2] == '__'}.
29
+ map(&:to_sym))
28
30
 
29
31
  include Enumerable
30
32
 
@@ -29,17 +29,17 @@ module RDF; module Util
29
29
  # to override this implementation to provide more control over HTTP
30
30
  # headers and redirect following.
31
31
  # @option options [Array, String] :headers
32
- # HTTP Request headers, passed to Kernel.open.
32
+ # HTTP Request headers, passed to Kernel.open. (Ruby >= 1.9 only)
33
33
  # @return [IO] File stream
34
34
  # @yield [IO] File stream
35
35
  # @note HTTP headers not passed to `Kernel.open` for Ruby versions < 1.9.
36
36
  def self.open_file(filename_or_url, options = {}, &block)
37
37
  filename_or_url = $1 if filename_or_url.to_s.match(/^file:(.*)$/)
38
- options[:headers] ||= {}
39
- options[:headers]['Accept'] ||= RDF::Reader.map {|r| r.format.content_type}.uniq.join(", ")
40
38
  if RUBY_VERSION < "1.9"
41
39
  Kernel.open(filename_or_url.to_s, &block)
42
40
  else
41
+ options[:headers] ||= {}
42
+ options[:headers]['Accept'] ||= (RDF::Format.reader_types + %w(*/*;q=0.1)).join(", ")
43
43
  Kernel.open(filename_or_url.to_s, options[:headers], &block)
44
44
  end
45
45
  end
@@ -129,7 +129,11 @@ module RDF
129
129
  end
130
130
 
131
131
  # Undefine all superfluous instance methods:
132
- undef_method(*(instance_methods.map(&:to_sym) - [:__id__, :__send__, :__class__, :__eval__, :object_id, :instance_eval, :inspect, :class, :is_a?]))
132
+ undef_method(*instance_methods.
133
+ map(&:to_s).
134
+ select {|m| m =~ /^\w+$/}.
135
+ reject {|m| %w(object_id dup instance_eval inspect to_s class).include?(m) || m[0,2] == '__'}.
136
+ map(&:to_sym))
133
137
 
134
138
  ##
135
139
  # @param [RDF::URI, String, #to_s] uri
@@ -466,8 +466,13 @@ module RDF
466
466
  # @param [String] string
467
467
  # @return [String]
468
468
  def escaped(string)
469
- string.gsub('\\', '\\\\').gsub("\t", '\\t').
470
- gsub("\n", '\\n').gsub("\r", '\\r').gsub('"', '\\"')
469
+ string.gsub('\\', '\\\\').
470
+ gsub("\b", '\\b').
471
+ gsub("\f", '\\f').
472
+ gsub("\t", '\\t').
473
+ gsub("\n", '\\n').
474
+ gsub("\r", '\\r').
475
+ gsub('"', '\\"')
471
476
  end
472
477
 
473
478
  ##
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
5
- prerelease:
4
+ version: 1.0.4
6
5
  platform: ruby
7
6
  authors:
8
7
  - Arto Bendiken
@@ -11,12 +10,11 @@ authors:
11
10
  autorequire:
12
11
  bindir: bin
13
12
  cert_chain: []
14
- date: 2013-02-26 00:00:00.000000000 Z
13
+ date: 2013-03-23 00:00:00.000000000 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: addressable
18
17
  requirement: !ruby/object:Gem::Requirement
19
- none: false
20
18
  requirements:
21
19
  - - ! '>='
22
20
  - !ruby/object:Gem::Version
@@ -24,7 +22,6 @@ dependencies:
24
22
  type: :runtime
25
23
  prerelease: false
26
24
  version_requirements: !ruby/object:Gem::Requirement
27
- none: false
28
25
  requirements:
29
26
  - - ! '>='
30
27
  - !ruby/object:Gem::Version
@@ -32,7 +29,6 @@ dependencies:
32
29
  - !ruby/object:Gem::Dependency
33
30
  name: rdf-spec
34
31
  requirement: !ruby/object:Gem::Requirement
35
- none: false
36
32
  requirements:
37
33
  - - ~>
38
34
  - !ruby/object:Gem::Version
@@ -40,7 +36,6 @@ dependencies:
40
36
  type: :development
41
37
  prerelease: false
42
38
  version_requirements: !ruby/object:Gem::Requirement
43
- none: false
44
39
  requirements:
45
40
  - - ~>
46
41
  - !ruby/object:Gem::Version
@@ -48,7 +43,6 @@ dependencies:
48
43
  - !ruby/object:Gem::Dependency
49
44
  name: rspec
50
45
  requirement: !ruby/object:Gem::Requirement
51
- none: false
52
46
  requirements:
53
47
  - - ! '>='
54
48
  - !ruby/object:Gem::Version
@@ -56,7 +50,6 @@ dependencies:
56
50
  type: :development
57
51
  prerelease: false
58
52
  version_requirements: !ruby/object:Gem::Requirement
59
- none: false
60
53
  requirements:
61
54
  - - ! '>='
62
55
  - !ruby/object:Gem::Version
@@ -64,7 +57,6 @@ dependencies:
64
57
  - !ruby/object:Gem::Dependency
65
58
  name: yard
66
59
  requirement: !ruby/object:Gem::Requirement
67
- none: false
68
60
  requirements:
69
61
  - - ! '>='
70
62
  - !ruby/object:Gem::Version
@@ -72,7 +64,6 @@ dependencies:
72
64
  type: :development
73
65
  prerelease: false
74
66
  version_requirements: !ruby/object:Gem::Requirement
75
- none: false
76
67
  requirements:
77
68
  - - ! '>='
78
69
  - !ruby/object:Gem::Version
@@ -170,30 +161,26 @@ files:
170
161
  homepage: http://ruby-rdf.github.com/
171
162
  licenses:
172
163
  - Public Domain
164
+ metadata: {}
173
165
  post_install_message:
174
166
  rdoc_options: []
175
167
  require_paths:
176
168
  - lib
177
169
  required_ruby_version: !ruby/object:Gem::Requirement
178
- none: false
179
170
  requirements:
180
171
  - - ! '>='
181
172
  - !ruby/object:Gem::Version
182
173
  version: 1.8.1
183
174
  required_rubygems_version: !ruby/object:Gem::Requirement
184
- none: false
185
175
  requirements:
186
176
  - - ! '>='
187
177
  - !ruby/object:Gem::Version
188
178
  version: '0'
189
- segments:
190
- - 0
191
- hash: -2150851322746438702
192
179
  requirements: []
193
180
  rubyforge_project: rdf
194
- rubygems_version: 1.8.25
181
+ rubygems_version: 2.0.3
195
182
  signing_key:
196
- specification_version: 3
183
+ specification_version: 4
197
184
  summary: A Ruby library for working with Resource Description Framework (RDF) data.
198
185
  test_files: []
199
186
  has_rdoc: false