openlogic-rdf 0.3.6

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.
Files changed (80) hide show
  1. data/AUTHORS +3 -0
  2. data/CREDITS +9 -0
  3. data/README +361 -0
  4. data/UNLICENSE +24 -0
  5. data/VERSION +1 -0
  6. data/bin/rdf +18 -0
  7. data/etc/doap.nt +62 -0
  8. data/lib/df.rb +1 -0
  9. data/lib/rdf/cli.rb +200 -0
  10. data/lib/rdf/format.rb +383 -0
  11. data/lib/rdf/mixin/countable.rb +39 -0
  12. data/lib/rdf/mixin/durable.rb +31 -0
  13. data/lib/rdf/mixin/enumerable.rb +637 -0
  14. data/lib/rdf/mixin/indexable.rb +26 -0
  15. data/lib/rdf/mixin/inferable.rb +5 -0
  16. data/lib/rdf/mixin/mutable.rb +191 -0
  17. data/lib/rdf/mixin/queryable.rb +265 -0
  18. data/lib/rdf/mixin/readable.rb +15 -0
  19. data/lib/rdf/mixin/type_check.rb +21 -0
  20. data/lib/rdf/mixin/writable.rb +152 -0
  21. data/lib/rdf/model/graph.rb +263 -0
  22. data/lib/rdf/model/list.rb +731 -0
  23. data/lib/rdf/model/literal/boolean.rb +121 -0
  24. data/lib/rdf/model/literal/date.rb +73 -0
  25. data/lib/rdf/model/literal/datetime.rb +72 -0
  26. data/lib/rdf/model/literal/decimal.rb +86 -0
  27. data/lib/rdf/model/literal/double.rb +189 -0
  28. data/lib/rdf/model/literal/integer.rb +126 -0
  29. data/lib/rdf/model/literal/numeric.rb +184 -0
  30. data/lib/rdf/model/literal/time.rb +87 -0
  31. data/lib/rdf/model/literal/token.rb +47 -0
  32. data/lib/rdf/model/literal/xml.rb +39 -0
  33. data/lib/rdf/model/literal.rb +373 -0
  34. data/lib/rdf/model/node.rb +156 -0
  35. data/lib/rdf/model/resource.rb +28 -0
  36. data/lib/rdf/model/statement.rb +296 -0
  37. data/lib/rdf/model/term.rb +77 -0
  38. data/lib/rdf/model/uri.rb +570 -0
  39. data/lib/rdf/model/value.rb +133 -0
  40. data/lib/rdf/nquads.rb +152 -0
  41. data/lib/rdf/ntriples/format.rb +48 -0
  42. data/lib/rdf/ntriples/reader.rb +239 -0
  43. data/lib/rdf/ntriples/writer.rb +219 -0
  44. data/lib/rdf/ntriples.rb +104 -0
  45. data/lib/rdf/query/pattern.rb +329 -0
  46. data/lib/rdf/query/solution.rb +252 -0
  47. data/lib/rdf/query/solutions.rb +237 -0
  48. data/lib/rdf/query/variable.rb +221 -0
  49. data/lib/rdf/query.rb +404 -0
  50. data/lib/rdf/reader.rb +511 -0
  51. data/lib/rdf/repository.rb +389 -0
  52. data/lib/rdf/transaction.rb +161 -0
  53. data/lib/rdf/util/aliasing.rb +63 -0
  54. data/lib/rdf/util/cache.rb +139 -0
  55. data/lib/rdf/util/file.rb +38 -0
  56. data/lib/rdf/util/uuid.rb +36 -0
  57. data/lib/rdf/util.rb +6 -0
  58. data/lib/rdf/version.rb +19 -0
  59. data/lib/rdf/vocab/cc.rb +18 -0
  60. data/lib/rdf/vocab/cert.rb +13 -0
  61. data/lib/rdf/vocab/dc.rb +63 -0
  62. data/lib/rdf/vocab/dc11.rb +23 -0
  63. data/lib/rdf/vocab/doap.rb +45 -0
  64. data/lib/rdf/vocab/exif.rb +168 -0
  65. data/lib/rdf/vocab/foaf.rb +69 -0
  66. data/lib/rdf/vocab/geo.rb +13 -0
  67. data/lib/rdf/vocab/http.rb +26 -0
  68. data/lib/rdf/vocab/owl.rb +59 -0
  69. data/lib/rdf/vocab/rdfs.rb +17 -0
  70. data/lib/rdf/vocab/rsa.rb +12 -0
  71. data/lib/rdf/vocab/rss.rb +14 -0
  72. data/lib/rdf/vocab/sioc.rb +93 -0
  73. data/lib/rdf/vocab/skos.rb +36 -0
  74. data/lib/rdf/vocab/wot.rb +21 -0
  75. data/lib/rdf/vocab/xhtml.rb +9 -0
  76. data/lib/rdf/vocab/xsd.rb +58 -0
  77. data/lib/rdf/vocab.rb +215 -0
  78. data/lib/rdf/writer.rb +475 -0
  79. data/lib/rdf.rb +192 -0
  80. metadata +173 -0
@@ -0,0 +1,373 @@
1
+ module RDF
2
+ ##
3
+ # An RDF literal.
4
+ #
5
+ # Subclasses of {RDF::Literal} should define DATATYPE and GRAMMAR constants, which are used
6
+ # for identifying the appropriate class to use for a datatype URI and to perform lexical
7
+ # matching on the value.
8
+ #
9
+ # Literal comparison with other {RDF::Value} instances call {RDF::Value#type_error},
10
+ # which, returns false. Implementations wishing to have {RDF::TypeError} raised
11
+ # should mix-in {RDF::TypeCheck}. This is required for strict SPARQL conformance.
12
+ #
13
+ # Specific typed literals may have behavior different from the default implementation. See
14
+ # the following defined sub-classes for specific documentation. Additional sub-classes may
15
+ # be defined, and will interoperate by defining `DATATYPE` and `GRAMMAR` constants, in addition
16
+ # other required overrides of RDF::Literal behavior.
17
+ #
18
+ # * {RDF::Literal::Boolean}
19
+ # * {RDF::Literal::Date}
20
+ # * {RDF::Literal::DateTime}
21
+ # * {RDF::Literal::Decimal}
22
+ # * {RDF::Literal::Double}
23
+ # * {RDF::Literal::Integer}
24
+ # * {RDF::Literal::Time}
25
+ #
26
+ # @example Creating a plain literal
27
+ # value = RDF::Literal.new("Hello, world!")
28
+ # value.plain? #=> true`
29
+ #
30
+ # @example Creating a language-tagged literal (1)
31
+ # value = RDF::Literal.new("Hello!", :language => :en)
32
+ # value.has_language? #=> true
33
+ # value.language #=> :en
34
+ #
35
+ # @example Creating a language-tagged literal (2)
36
+ # RDF::Literal.new("Wazup?", :language => :"en-US")
37
+ # RDF::Literal.new("Hej!", :language => :sv)
38
+ # RDF::Literal.new("¡Hola!", :language => :es)
39
+ #
40
+ # @example Creating an explicitly datatyped literal
41
+ # value = RDF::Literal.new("2009-12-31", :datatype => RDF::XSD.date)
42
+ # value.has_datatype? #=> true
43
+ # value.datatype #=> RDF::XSD.date
44
+ #
45
+ # @example Creating an implicitly datatyped literal
46
+ # value = RDF::Literal.new(Date.today)
47
+ # value.has_datatype? #=> true
48
+ # value.datatype #=> RDF::XSD.date
49
+ #
50
+ # @example Creating implicitly datatyped literals
51
+ # RDF::Literal.new(false).datatype #=> XSD.boolean
52
+ # RDF::Literal.new(true).datatype #=> XSD.boolean
53
+ # RDF::Literal.new(123).datatype #=> XSD.integer
54
+ # RDF::Literal.new(9223372036854775807).datatype #=> XSD.integer
55
+ # RDF::Literal.new(3.1415).datatype #=> XSD.double
56
+ # RDF::Literal.new(Time.now).datatype #=> XSD.dateTime
57
+ # RDF::Literal.new(Date.new(2010)).datatype #=> XSD.date
58
+ # RDF::Literal.new(DateTime.new(2010)).datatype #=> XSD.dateTime
59
+ #
60
+ # @see http://www.w3.org/TR/rdf-concepts/#section-Literals
61
+ # @see http://www.w3.org/TR/rdf-concepts/#section-Datatypes-intro
62
+ class Literal
63
+
64
+ private
65
+ @@subclasses = [] # @private
66
+
67
+ ##
68
+ # @private
69
+ # @return [void]
70
+ def self.inherited(child)
71
+ @@subclasses << child
72
+ super
73
+ end
74
+
75
+ public
76
+
77
+ require 'rdf/model/literal/numeric'
78
+ require 'rdf/model/literal/boolean'
79
+ require 'rdf/model/literal/decimal'
80
+ require 'rdf/model/literal/integer'
81
+ require 'rdf/model/literal/double'
82
+ require 'rdf/model/literal/date'
83
+ require 'rdf/model/literal/datetime'
84
+ require 'rdf/model/literal/time'
85
+ require 'rdf/model/literal/token'
86
+ require 'rdf/model/literal/xml'
87
+
88
+ include RDF::Term
89
+
90
+ ##
91
+ # @private
92
+ # Return datatype class for uri, or nil if none is found
93
+ def self.datatyped_class(uri)
94
+ @@subclasses.detect {|klass| klass.const_defined?(:DATATYPE) && klass.const_get(:DATATYPE) == uri}
95
+ end
96
+
97
+ ##
98
+ # @private
99
+ def self.new(value, options = {})
100
+ klass = case
101
+ when !self.equal?(RDF::Literal)
102
+ self # subclasses can be directly constructed without type dispatch
103
+ when typed_literal = datatyped_class(RDF::URI(options[:datatype]))
104
+ typed_literal
105
+ else case value
106
+ when ::TrueClass then RDF::Literal::Boolean
107
+ when ::FalseClass then RDF::Literal::Boolean
108
+ when ::Integer then RDF::Literal::Integer
109
+ when ::Float then RDF::Literal::Double
110
+ when ::BigDecimal then RDF::Literal::Decimal
111
+ when ::DateTime then RDF::Literal::DateTime
112
+ when ::Date then RDF::Literal::Date
113
+ when ::Time then RDF::Literal::Time # FIXME: Ruby's Time class can represent datetimes as well
114
+ when ::Symbol then RDF::Literal::Token
115
+ else self
116
+ end
117
+ end
118
+ literal = klass.allocate
119
+ literal.send(:initialize, value, options)
120
+ literal.validate! if options[:validate]
121
+ literal.canonicalize! if options[:canonicalize]
122
+ literal
123
+ end
124
+
125
+ TRUE = RDF::Literal.new(true).freeze
126
+ FALSE = RDF::Literal.new(false).freeze
127
+ ZERO = RDF::Literal.new(0).freeze
128
+
129
+ # @return [Symbol] The language tag (optional).
130
+ attr_accessor :language
131
+
132
+ # @return [URI] The XML Schema datatype URI (optional).
133
+ attr_accessor :datatype
134
+
135
+ ##
136
+ # @param [Object] value
137
+ # @option options [Symbol] :language (nil)
138
+ # @option options [URI] :datatype (nil)
139
+ def initialize(value, options = {})
140
+ @object = value
141
+ @string = options[:lexical] if options[:lexical]
142
+ @string = value if !defined?(@string) && value.is_a?(String)
143
+ @language = options[:language].to_s.to_sym if options[:language]
144
+ @datatype = RDF::URI(options[:datatype]) if options[:datatype]
145
+ @datatype ||= self.class.const_get(:DATATYPE) if self.class.const_defined?(:DATATYPE)
146
+ end
147
+
148
+ ##
149
+ # Returns the value as a string.
150
+ #
151
+ # @return [String]
152
+ def value
153
+ @string || to_s
154
+ end
155
+
156
+ ##
157
+ # @return [Object]
158
+ def object
159
+ defined?(@object) ? @object : value
160
+ end
161
+
162
+ ##
163
+ # Returns `true`.
164
+ #
165
+ # @return [Boolean] `true` or `false`
166
+ def literal?
167
+ true
168
+ end
169
+
170
+ ##
171
+ # Returns `false`.
172
+ #
173
+ # @return [Boolean] `true` or `false`
174
+ def anonymous?
175
+ false
176
+ end
177
+
178
+ ##
179
+ # Returns a hash code for this literal.
180
+ #
181
+ # @return [Fixnum]
182
+ def hash
183
+ to_s.hash
184
+ end
185
+
186
+ ##
187
+ # Determins if `self` is the same term as `other`.
188
+ #
189
+ # @example
190
+ # RDF::Literal(1).eql?(RDF::Literal(1.0)) #=> false
191
+ #
192
+ # @param [Object] other
193
+ # @return [Boolean] `true` or `false`
194
+ def eql?(other)
195
+ self.equal?(other) ||
196
+ (self.class.eql?(other.class) &&
197
+ self.value.eql?(other.value) &&
198
+ self.language.to_s.downcase.eql?(other.language.to_s.downcase) &&
199
+ self.datatype.eql?(other.datatype))
200
+ end
201
+
202
+ ##
203
+ # Returns `true` if this literal is equivalent to `other` (with type check).
204
+ #
205
+ # @example
206
+ # RDF::Literal(1) == RDF::Literal(1.0) #=> true
207
+ #
208
+ # @param [Object] other
209
+ # @return [Boolean] `true` or `false`
210
+ #
211
+ # @see http://www.w3.org/TR/rdf-sparql-query/#func-RDFterm-equal
212
+ # @see http://www.w3.org/TR/rdf-concepts/#section-Literal-Equality
213
+ def ==(other)
214
+ case other
215
+ when Literal
216
+ case
217
+ when self.eql?(other)
218
+ true
219
+ when self.has_language? && self.language.to_s.downcase == other.language.to_s.downcase
220
+ # Literals with languages can compare if languages are identical
221
+ self.value == other.value
222
+ when (self.simple? || self.datatype == XSD.string) && (other.simple? || other.datatype == XSD.string)
223
+ self.value == other.value
224
+ when other.comperable_datatype?(self) || self.comperable_datatype?(other)
225
+ # Comoparing plain with undefined datatypes does not generate an error, but returns false
226
+ # From data-r2/expr-equal/eq-2-2.
227
+ false
228
+ else
229
+ type_error("unable to determine whether #{self.inspect} and #{other.inspect} are equivalent")
230
+ end
231
+ when String
232
+ self.plain? && self.value.eql?(other)
233
+ else false
234
+ end
235
+ end
236
+ alias_method :===, :==
237
+
238
+ ##
239
+ # Returns `true` if this is a plain literal.
240
+ #
241
+ # @return [Boolean] `true` or `false`
242
+ # @see http://www.w3.org/TR/rdf-concepts/#dfn-plain-literal
243
+ def plain?
244
+ language.nil? && datatype.nil?
245
+ end
246
+ alias_method :simple?, :plain?
247
+
248
+ ##
249
+ # Returns `true` if this is a language-tagged literal.
250
+ #
251
+ # @return [Boolean] `true` or `false`
252
+ # @see http://www.w3.org/TR/rdf-concepts/#dfn-plain-literal
253
+ def has_language?
254
+ !language.nil?
255
+ end
256
+ alias_method :language?, :has_language?
257
+
258
+ ##
259
+ # Returns `true` if this is a datatyped literal.
260
+ #
261
+ # @return [Boolean] `true` or `false`
262
+ # @see http://www.w3.org/TR/rdf-concepts/#dfn-typed-literal
263
+ def has_datatype?
264
+ !datatype.nil?
265
+ end
266
+ alias_method :datatype?, :has_datatype?
267
+ alias_method :typed?, :has_datatype?
268
+ alias_method :datatyped?, :has_datatype?
269
+
270
+ ##
271
+ # Returns `true` if the value adheres to the defined grammar of the
272
+ # datatype.
273
+ #
274
+ # @return [Boolean] `true` or `false`
275
+ # @since 0.2.1
276
+ def valid?
277
+ grammar = self.class.const_get(:GRAMMAR) rescue nil
278
+ grammar.nil? || !!(value =~ grammar)
279
+ end
280
+
281
+ ##
282
+ # Returns `true` if the value does not adhere to the defined grammar of
283
+ # the datatype.
284
+ #
285
+ # @return [Boolean] `true` or `false`
286
+ # @since 0.2.1
287
+ def invalid?
288
+ !valid?
289
+ end
290
+
291
+ ##
292
+ # Returns `true` if the literal has a datatype and the comparison should
293
+ # return false instead of raise a type error.
294
+ #
295
+ # This behavior is intuited from SPARQL data-r2/expr-equal/eq-2-2
296
+ # @return [Boolean]
297
+ def comperable_datatype?(other)
298
+ return false unless self.plain? || self.has_language?
299
+
300
+ case other
301
+ when RDF::Literal::Numeric, RDF::Literal::Boolean,
302
+ RDF::Literal::Date, RDF::Literal::Time, RDF::Literal::DateTime
303
+ # Invald types can be compared without raising a TypeError if literal has a language (open-eq-08)
304
+ !other.valid? && self.has_language?
305
+ else
306
+ case other.datatype
307
+ when XSD.string
308
+ true
309
+ when nil
310
+ # A different language will not generate a type error
311
+ other.has_language?
312
+ else
313
+ # An unknown datatype may not be used for comparison, unless it has a language? (open-eq-8)
314
+ self.has_language?
315
+ end
316
+ end
317
+ end
318
+
319
+ ##
320
+ # Validates the value using {#valid?}, raising an error if the value is
321
+ # invalid.
322
+ #
323
+ # @return [RDF::Literal] `self`
324
+ # @raise [ArgumentError] if the value is invalid
325
+ # @since 0.2.1
326
+ def validate!
327
+ raise ArgumentError, "#{to_s.inspect} is not a valid <#{datatype.to_s}> literal" if invalid?
328
+ self
329
+ end
330
+ alias_method :validate, :validate!
331
+
332
+ ##
333
+ # Returns a copy of this literal converted into its canonical lexical
334
+ # representation.
335
+ #
336
+ # Subclasses should override `#canonicalize!` as needed and appropriate,
337
+ # not this method.
338
+ #
339
+ # @return [RDF::Literal]
340
+ # @since 0.2.1
341
+ def canonicalize
342
+ self.dup.canonicalize!
343
+ end
344
+
345
+ ##
346
+ # Converts this literal into its canonical lexical representation.
347
+ #
348
+ # Subclasses should override this as needed and appropriate.
349
+ #
350
+ # @return [RDF::Literal] `self`
351
+ # @since 0.3.0
352
+ def canonicalize!
353
+ @language = @language.to_s.downcase.to_sym if @language
354
+ self
355
+ end
356
+
357
+ ##
358
+ # Returns the value as a string.
359
+ #
360
+ # @return [String]
361
+ def to_s
362
+ @object.to_s
363
+ end
364
+
365
+ ##
366
+ # Returns a developer-friendly representation of `self`.
367
+ #
368
+ # @return [String]
369
+ def inspect
370
+ sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, RDF::NTriples.serialize(self))
371
+ end
372
+ end # Literal
373
+ end # RDF
@@ -0,0 +1,156 @@
1
+ module RDF
2
+ ##
3
+ # An RDF blank node, also known as an anonymous or unlabeled node.
4
+ #
5
+ # @example Creating a blank node with an implicit identifier
6
+ # bnode = RDF::Node.new
7
+ #
8
+ # @example Creating a blank node with an UUID identifier
9
+ # bnode = RDF::Node.uuid
10
+ # bnode.to_s #=> "_:504c0a30-0d11-012d-3f50-001b63cac539"
11
+ #
12
+ class Node
13
+ include RDF::Resource
14
+
15
+ ##
16
+ # Returns a blank node with a random UUID-based identifier.
17
+ #
18
+ # @param [Hash{Symbol => Object}] options
19
+ # @option options [Regexp] :grammar (nil)
20
+ # a grammar specification that the generated UUID must match
21
+ # @return [RDF::Node]
22
+ def self.uuid(options = {})
23
+ case
24
+ when options[:grammar]
25
+ # The UUID is generated such that its initial part is guaranteed
26
+ # to match the given `grammar`, e.g. `/^[A-Za-z][A-Za-z0-9]*/`.
27
+ # Some RDF storage systems (e.g. AllegroGraph) require this.
28
+ # @see http://github.com/bendiken/rdf/pull/43
29
+ uuid = RDF::Util::UUID.generate(options) until uuid =~ options[:grammar]
30
+ else
31
+ uuid = RDF::Util::UUID.generate(options)
32
+ end
33
+ self.new(uuid)
34
+ end
35
+
36
+ ##
37
+ # Alias for `RDF::Node.new`, at the moment.
38
+ #
39
+ # @private
40
+ # @param [#to_s] id
41
+ # @return [RDF::Node]
42
+ # @since 0.2.0
43
+ def self.intern(id)
44
+ self.new(id)
45
+ end
46
+
47
+ ##
48
+ # Override #dup to remember original object.
49
+ # This allows .eql? to determine that two nodes
50
+ # are the same thing, and not different nodes
51
+ # instantiated with the same identifier.
52
+ # @return [RDF::Node]
53
+ def dup
54
+ node = super
55
+ node.original = self.original || self
56
+ node
57
+ end
58
+
59
+ ##
60
+ # Originally instantiated node, if any
61
+ # @return [RDF::Node]
62
+ attr_accessor :original
63
+
64
+ # @return [String]
65
+ attr_accessor :id
66
+
67
+ ##
68
+ # @param [#to_s] id
69
+ def initialize(id = nil)
70
+ @id = (id || "g#{__id__.to_i.abs}").to_s
71
+ end
72
+
73
+ ##
74
+ # Returns `true`.
75
+ #
76
+ # @return [Boolean]
77
+ def node?
78
+ true
79
+ end
80
+
81
+ ##
82
+ # Returns `true`.
83
+ #
84
+ # @return [Boolean]
85
+ def anonymous?
86
+ true
87
+ end
88
+
89
+ alias_method :unlabeled?, :anonymous?
90
+
91
+ ##
92
+ # Returns `false`.
93
+ #
94
+ # @return [Boolean]
95
+ def labeled?
96
+ !unlabeled?
97
+ end
98
+
99
+ ##
100
+ # Returns a hash code for this blank node.
101
+ #
102
+ # @return [Fixnum]
103
+ def hash
104
+ @id.hash
105
+ end
106
+
107
+ ##
108
+ # Determins if `self` is the same term as `other`.
109
+ #
110
+ # In this case, nodes must be the same object
111
+ #
112
+ # @param [Node] other
113
+ # @return [Boolean]
114
+ def eql?(other)
115
+ other.is_a?(RDF::Node) && (self.original || self).equal?(other.original || other)
116
+ end
117
+
118
+ ##
119
+ # Checks whether this blank node is equal to `other` (type checking).
120
+ #
121
+ # In this case, different nodes having the same id are considered the same.
122
+ #
123
+ # Per SPARQL data-r2/expr-equal/eq-2-2, numeric can't be compared with other types
124
+ #
125
+ # @param [Object] other
126
+ # @return [Boolean]
127
+ # @see http://www.w3.org/TR/rdf-sparql-query/#func-RDFterm-equal
128
+ def ==(other)
129
+ case other
130
+ when Literal
131
+ # If other is a Literal, reverse test to consolodate complex type checking logic
132
+ other == self
133
+ else
134
+ other.respond_to?(:node?) && other.node? && other.respond_to?(:id) && @id == other.id
135
+ end
136
+ end
137
+ alias_method :===, :==
138
+
139
+ ##
140
+ # Returns a string representation of this blank node.
141
+ #
142
+ # @return [String]
143
+ def to_s
144
+ "_:%s" % @id.to_s
145
+ end
146
+
147
+ ##
148
+ # Returns a symbol representation of this blank node.
149
+ #
150
+ # @return [Symbol]
151
+ # @since 0.2.0
152
+ def to_sym
153
+ @id.to_s.to_sym
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,28 @@
1
+ module RDF
2
+ ##
3
+ # An RDF resource.
4
+ module Resource
5
+ include RDF::Term
6
+
7
+ ##
8
+ # Instantiates an {RDF::Node} or an {RDF::URI}, depending on the given
9
+ # argument.
10
+ #
11
+ # @return [RDF::Resource]
12
+ def self.new(*args, &block)
13
+ case arg = args.shift
14
+ when Symbol then Node.intern(arg, *args, &block)
15
+ when /^_:(.*)$/ then Node.new($1, *args, &block)
16
+ else URI.new(arg, *args, &block)
17
+ end
18
+ end
19
+
20
+ ##
21
+ # Returns `true` to indicate that this value is a resource.
22
+ #
23
+ # @return [Boolean]
24
+ def resource?
25
+ true
26
+ end
27
+ end # Resource
28
+ end # RDF