active-triples 0.10.2 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -1
  3. data/CHANGES.md +17 -11
  4. data/README.md +72 -39
  5. data/lib/active_triples/configurable.rb +6 -1
  6. data/lib/active_triples/list.rb +1 -4
  7. data/lib/active_triples/nested_attributes.rb +10 -7
  8. data/lib/active_triples/persistable.rb +13 -0
  9. data/lib/active_triples/persistence_strategies/parent_strategy.rb +47 -34
  10. data/lib/active_triples/persistence_strategies/persistence_strategy.rb +14 -1
  11. data/lib/active_triples/properties.rb +19 -4
  12. data/lib/active_triples/property_builder.rb +4 -4
  13. data/lib/active_triples/rdf_source.rb +142 -189
  14. data/lib/active_triples/relation.rb +307 -156
  15. data/lib/active_triples/util/buffered_transaction.rb +126 -0
  16. data/lib/active_triples/util/extended_bounded_description.rb +75 -0
  17. data/lib/active_triples/version.rb +1 -1
  18. data/spec/active_triples/configurable_spec.rb +35 -7
  19. data/spec/active_triples/identifiable_spec.rb +19 -6
  20. data/spec/active_triples/list_spec.rb +15 -7
  21. data/spec/active_triples/nested_attributes_spec.rb +12 -10
  22. data/spec/active_triples/persistable_spec.rb +0 -4
  23. data/spec/active_triples/persistence_strategies/parent_strategy_spec.rb +57 -10
  24. data/spec/active_triples/rdf_source_spec.rb +137 -97
  25. data/spec/active_triples/relation_spec.rb +436 -132
  26. data/spec/active_triples/resource_spec.rb +8 -23
  27. data/spec/active_triples/util/buffered_transaction_spec.rb +187 -0
  28. data/spec/active_triples/util/extended_bounded_description_spec.rb +98 -0
  29. data/spec/integration/reciprocal_properties_spec.rb +10 -10
  30. data/spec/support/matchers.rb +13 -1
  31. metadata +7 -3
@@ -21,6 +21,9 @@ module ActiveTriples
21
21
  # @see RDF::Term
22
22
  class Relation
23
23
  include Enumerable
24
+ include Comparable
25
+
26
+ TYPE_PROPERTY = { predicate: RDF.type, cast: false }.freeze
24
27
 
25
28
  # @!attribute [rw] parent
26
29
  # @return [RDFSource] the resource that is the domain of this relation
@@ -33,8 +36,7 @@ module ActiveTriples
33
36
  attr_accessor :parent, :value_arguments, :rel_args
34
37
  attr_reader :reflections
35
38
 
36
- delegate :<=>, :==, :===, :[], :each, :empty?, :equal, :inspect, :last,
37
- :to_a, :to_ary, :size, :join, :length, :+, :to => :result
39
+ delegate :[], :inspect, :last, :size, :join, to: :to_a
38
40
 
39
41
  ##
40
42
  # @param [ActiveTriples::RDFSource] parent_source
@@ -44,95 +46,101 @@ module ActiveTriples
44
46
  self.parent = parent_source
45
47
  @reflections = parent_source.reflections
46
48
  self.rel_args ||= {}
47
- self.rel_args = value_arguments.pop if value_arguments.is_a?(Array) &&
48
- value_arguments.last.is_a?(Hash)
49
+ self.rel_args = value_arguments.pop if
50
+ value_arguments.is_a?(Array) && value_arguments.last.is_a?(Hash)
51
+
49
52
  self.value_arguments = value_arguments
50
53
  end
51
54
 
52
55
  ##
53
- # Empties the `Relation`, deleting any associated triples from `parent`.
56
+ # @param array [#to_ary, ActiveTriples::Relation]
57
+ # @return [Array]
54
58
  #
55
- # @return [Relation] self; a now empty relation
56
- def clear
57
- parent.delete([rdf_subject, predicate, nil])
59
+ # @note simply passes to `Array#&` unless argument is a `Relation`
60
+ #
61
+ # @see Array#&
62
+ def &(array)
63
+ return to_a & array unless array.is_a? Relation
58
64
 
59
- self
65
+ (objects.to_a & array.objects.to_a)
66
+ .map { |object| convert_object(object) }
60
67
  end
61
-
68
+
62
69
  ##
63
- # Gives an {Array} containing the result set for the {Relation}.
70
+ # @param array [#to_ary, ActiveTriples::Relation]
71
+ # @return [Array]
64
72
  #
65
- # By default, {RDF::URI} and {RDF::Node} results are cast to `RDFSource`.
66
- # {Literal} results are given as their `#object` representations (e.g.
67
- # {String}, {Date}.
73
+ # @note simply passes to `Array#|` unless argument is a `Relation`
68
74
  #
69
- # @example results with default casting
70
- # parent << [parent.rdf_subject, predicate, 'my value']
71
- # parent << [parent.rdf_subject, predicate, Date.today]
72
- # parent << [parent.rdf_subject, predicate, RDF::URI('http://ex.org/#me')]
73
- # parent << [parent.rdf_subject, predicate, RDF::Node.new]
74
- # relation.result
75
- # # => ["my_value",
76
- # # Fri, 25 Sep 2015,
77
- # # #<ActiveTriples::Resource:0x3f8...>,
78
- # # #<ActiveTriples::Resource:0x3f8...>]
75
+ # @see Array#|
76
+ def |(array)
77
+ return to_a | array unless array.is_a? Relation
78
+
79
+ (objects.to_a | array.objects.to_a)
80
+ .map { |object| convert_object(object) }
81
+ end
82
+
83
+ ##
84
+ # @param array [#to_ary, ActiveTriples::Relation]
85
+ # @return [Array]
79
86
  #
80
- # When `cast?` is `false`, {RDF::Resource} values are left in their raw
81
- # form. Similarly, when `#return_literals?` is `true`, literals are
82
- # returned in their {RDF::Literal} form, preserving language tags,
83
- # datatype, and value.
87
+ # @note simply passes to `Array#+` unless argument is a `Relation`
84
88
  #
85
- # @example results with `cast?` set to `false`
86
- # relation.result
87
- # # => ["my_value",
88
- # # Fri, 25 Sep 2015,
89
- # # #<RDF::URI:0x3f8... URI:http://ex.org/#me>,
90
- # # #<RDF::Node:0x3f8...(_:g69843536054680)>]
89
+ # @see Array#+
90
+ def +(array)
91
+ return to_a + array unless array.is_a? Relation
92
+
93
+ (objects.to_a + array.objects.to_a)
94
+ .map { |object| convert_object(object) }
95
+ end
96
+
97
+ ##
98
+ # Mimics `Set#<=>`, returning `0` when set membership is equivalent, and
99
+ # `nil` (as non-comparable) otherwise. Unlike `Set#<=>`, uses `#==` for
100
+ # member comparisons.
91
101
  #
92
- # @example results with `return_literals?` set to `true`
93
- # relation.result
94
- # # => [#<RDF::Literal:0x3f8...("my_value")>,
95
- # # #<RDF::Literal::Date:0x3f8...("2015-09-25"^^<http://www.w3.org/2001/XMLSchema#date>)>,
96
- # # #<ActiveTriples::Resource:0x3f8...>,
97
- # # #<ActiveTriples::Resource:0x3f8...>]
102
+ # @param [Object] other
98
103
  #
99
- # @return [Array<Object>] the result set
100
- def result
101
- return [] if predicate.nil?
102
- statements = parent.query(:subject => rdf_subject,
103
- :predicate => predicate)
104
- statements.each_with_object([]) do |x, collector|
105
- converted_object = convert_object(x.object)
106
- collector << converted_object unless converted_object.nil?
104
+ # @see Set#<=>
105
+ def <=>(other)
106
+ return nil unless other.respond_to?(:each)
107
+
108
+ if empty?
109
+ return 0 if other.each.first.nil?
110
+ return nil
111
+ end
112
+
113
+ # We'll need to traverse `other` repeatedly, so we get a stable `Array`
114
+ # representation. This avoids any repeated query cost if `other` is a
115
+ # `Relation`.
116
+ length = 0
117
+ other = other.to_a
118
+ this = each
119
+
120
+ loop do
121
+ begin
122
+ cur = this.next
123
+ rescue StopIteration
124
+ return other.length == length ? 0 : nil
125
+ end
126
+
127
+ length += 1
128
+
129
+ return nil if other.length < length || !other.include?(cur)
107
130
  end
108
131
  end
109
132
 
110
133
  ##
111
- # Adds values to the relation
134
+ # Adds values to the result set
112
135
  #
113
- # @param [Array<RDF::Resource>, RDF::Resource] values an array of values
114
- # or a single value. If not an {RDF::Resource}, the values will be
115
- # coerced to an {RDF::Literal} or {RDF::Node} by {RDF::Statement}
136
+ # @param values [Object, Array<Object>] values to add
116
137
  #
117
138
  # @return [Relation] a relation containing the set values; i.e. `self`
118
- #
119
- # @raise [ActiveTriples::UndefinedPropertyError] if the property is not
120
- # already an {RDF::Term} and is not defined in `#property_config`
121
- #
122
- # @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Statement For
123
- # documentation on {RDF::Statement} and the handling of
124
- # non-{RDF::Resource} values.
125
- def set(values)
126
- raise UndefinedPropertyError.new(property, reflections) if predicate.nil?
127
- values = values.to_a if values.is_a? Relation
128
- values = [values].compact unless values.kind_of?(Array)
129
-
130
- clear
131
- values.each { |val| set_value(val) }
132
-
133
- parent.persist! if parent.persistence_strategy.is_a? ParentStrategy
134
- self
139
+ def <<(values)
140
+ values = prepare_relation(values) if values.is_a?(Relation)
141
+ self.set(objects.to_a | Array.wrap(values))
135
142
  end
143
+ alias_method :push, :<<
136
144
 
137
145
  ##
138
146
  # Builds a node with the given attributes, adding it to the relation.
@@ -195,17 +203,27 @@ module ActiveTriples
195
203
  end
196
204
 
197
205
  ##
198
- # @note this method behaves somewhat differently from `Array#delete`.
206
+ # Empties the `Relation`, deleting any associated triples from `parent`.
207
+ #
208
+ # @return [Relation] self; a now empty relation
209
+ def clear
210
+ parent.delete([rdf_subject, predicate, nil])
211
+
212
+ self
213
+ end
214
+
215
+ ##
216
+ # @note this method behaves somewhat differently from `Array#delete`.
199
217
  # It succeeds on deletion of non-existing values, always returning
200
- # `self` unless an error is raised. There is no option to pass a block
201
- # to evaluate if the value is not present. This is because access for
218
+ # `self` unless an error is raised. There is no option to pass a block
219
+ # to evaluate if the value is not present. This is because access for
202
220
  # `value` depends on query time. i.e. the `Relation` set does not have an
203
221
  # underlying efficient data structure allowing a reliably cheap existence
204
222
  # check.
205
223
  #
206
- # @note symbols are treated as RDF::Nodes by default in
224
+ # @note symbols are treated as RDF::Nodes by default in
207
225
  # `RDF::Mutable#delete`, but may also represent tokens in statements.
208
- # This casts symbols to a literals, which gets us symmetric behavior
226
+ # This casts symbols to a literals, which gets us symmetric behavior
209
227
  # between `#set(:sym)` and `#delete(:sym)`.
210
228
  #
211
229
  # @example deleting a value
@@ -219,7 +237,7 @@ module ActiveTriples
219
237
  # resource.title = 'moomin'
220
238
  # resource.title.delete('valley') # => ["moomin"]
221
239
  # resource.title # => ['moomin']
222
- #
240
+ #
223
241
  # @param value [Object] the value to delete from the relation
224
242
  # @return [ActiveTriples::Relation] self
225
243
  def delete(value)
@@ -230,12 +248,12 @@ module ActiveTriples
230
248
  end
231
249
 
232
250
  ##
233
- # A variation on `#delete`. This queries the relation for matching
251
+ # A variation on `#delete`. This queries the relation for matching
234
252
  # values before running the deletion, returning `nil` if it does not exist.
235
253
  #
236
254
  # @param value [Object] the value to delete from the relation
237
255
  #
238
- # @return [Object, nil] `nil` if the value doesn't exist; the value
256
+ # @return [Object, nil] `nil` if the value doesn't exist; the value
239
257
  # otherwise
240
258
  # @see #delete
241
259
  def delete?(value)
@@ -248,71 +266,94 @@ module ActiveTriples
248
266
  end
249
267
 
250
268
  ##
251
- # @overload subtract(enum)
252
- # Deletes objects in the enumerable from the relation
253
- # @param values [Enumerable] an enumerable of objects to delete
254
- # @overload subtract(*values)
255
- # Deletes each argument value from the relation
256
- # @param *values [Array<Object>] the objects to delete
269
+ # Gives a result set for the `Relation`.
257
270
  #
258
- # @return [Relation] self
271
+ # By default, `RDF::URI` and `RDF::Node` results are cast to `RDFSource`.
272
+ # When `cast?` is `false`, `RDF::Resource` values are left in their raw
273
+ # form.
259
274
  #
260
- # @note This casts symbols to a literals, which gets us symmetric behavior
261
- # with `#set(:sym)`.
262
- # @see #delete
263
- def subtract(*values)
264
- values = values.first if values.first.is_a? Enumerable
265
- statements = values.map do |value|
266
- value = RDF::Literal(value) if value.is_a? Symbol
267
- [rdf_subject, predicate, value]
275
+ # `Literal` results are cast as follows:
276
+ #
277
+ # - Simple string literals are returned as `String`
278
+ # - `rdf:langString` literals are always returned as raw `Literal` objects,
279
+ # retaining their language tags.
280
+ # - Typed literals are cast to their Ruby `#object` when their datatype
281
+ # is associated with a `Literal` subclass.
282
+ #
283
+ # @example results with default casting
284
+ # datatype = RDF::URI("http://example.com/custom_type")
285
+ #
286
+ # parent << [parent.rdf_subject, predicate, 'my value']
287
+ # parent << [parent.rdf_subject, predicate, RDF::Literal('my_value',
288
+ # datatype: datatype)]
289
+ # parent << [parent.rdf_subject, predicate, Date.today]
290
+ # parent << [parent.rdf_subject, predicate, RDF::URI('http://ex.org/#me')]
291
+ # parent << [parent.rdf_subject, predicate, RDF::Node.new]
292
+ #
293
+ # relation.to_a
294
+ # # => ["my_value",
295
+ # # "my_value" R:L:(Literal),
296
+ # # Fri, 25 Sep 2015,
297
+ # # #<ActiveTriples::Resource:0x3f8...>,
298
+ # # #<ActiveTriples::Resource:0x3f8...>]
299
+ #
300
+ # @example results with `cast?` set to `false`
301
+ # relation.to_a
302
+ # # => ["my_value",
303
+ # # "my_value" R:L:(Literal),
304
+ # # Fri, 25 Sep 2015,
305
+ # # #<RDF::URI:0x3f8... URI:http://ex.org/#me>,
306
+ # # #<RDF::Node:0x3f8...(_:g69843536054680)>]
307
+ #
308
+ # @return [Enumerator<Object>] the result set
309
+ def each
310
+ return [].to_enum if predicate.nil?
311
+
312
+ if block_given?
313
+ objects do |object|
314
+ converted_object = convert_object(object)
315
+ yield converted_object unless converted_object.nil?
316
+ end
268
317
  end
269
-
270
- parent.delete(*statements)
271
- self
318
+
319
+ to_enum
272
320
  end
273
321
 
274
322
  ##
275
- # Replaces the first argument with the second as a value within the
276
- # relation.
277
- #
278
- # @example
279
- #
280
- #
281
- # @param swap_out [Object] the value to delete
282
- # @param swap_in [Object] the replacement value
283
- #
284
- # @return [Relation] self
285
- def swap(swap_out, swap_in)
286
- self.<<(swap_in) if delete?(swap_out)
323
+ # @return [Boolean] true if the results are empty.
324
+ def empty?
325
+ objects.empty?
287
326
  end
288
327
 
289
328
  ##
329
+ # @deprecated for removal in 1.0.0. Use `first || build({})`,
330
+ # `build({}) if empty?` or similar logic.
331
+ #
290
332
  # @return [Object] the first result, if present; else a newly built node
291
333
  #
292
334
  # @see #build
293
335
  def first_or_create(attributes={})
294
- result.first || build(attributes)
336
+ warn 'DEPRECATION: #first_or_create is deprecated for removal in 1.0.0.'
337
+ first || build(attributes)
295
338
  end
296
339
 
297
340
  ##
298
- # Adds values to the result set
299
- #
300
- # @param values [Object, Array<Object>] values to add
301
- #
302
- # @return [Relation] a relation containing the set values; i.e. `self`
303
- def <<(values)
304
- values = Array.wrap(result) | Array.wrap(values)
305
- self.set(values)
341
+ # @return [Integer]
342
+ def length
343
+ objects.to_a.length
306
344
  end
307
- alias_method :push, :<<
308
345
 
309
346
  ##
310
- # @return [Hash<Symbol, ]
311
- # @todo find a way to simplify this?
312
- def property_config
313
- return type_property if is_type?
314
-
315
- reflections.reflect_on_property(property)
347
+ # Gives the predicate used by the Relation. Values of this object are
348
+ # those that match the pattern `<rdf_subject> <predicate> [value] .`
349
+ #
350
+ # @return [RDF::Term, nil] the predicate for this relation; nil if
351
+ # no predicate can be found
352
+ #
353
+ # @see #property
354
+ def predicate
355
+ return property if property.is_a?(RDF::Term)
356
+ property_config[:predicate] if is_property?
316
357
  end
317
358
 
318
359
  ##
@@ -326,33 +367,136 @@ module ActiveTriples
326
367
  end
327
368
 
328
369
  ##
329
- # Gives the predicate used by the Relation. Values of this object are
330
- # those that match the pattern `<rdf_subject> <predicate> [value] .`
370
+ # Adds values to the relation
331
371
  #
332
- # @return [RDF::Term, nil] the predicate for this relation; nil if
333
- # no predicate can be found
372
+ # @param [Array<RDF::Resource>, RDF::Resource] values an array of values
373
+ # or a single value. If not an {RDF::Resource}, the values will be
374
+ # coerced to an {RDF::Literal} or {RDF::Node} by {RDF::Statement}
334
375
  #
335
- # @see #property
336
- def predicate
337
- return property if property.is_a?(RDF::Term)
338
- property_config[:predicate] if is_property?
376
+ # @return [Relation] a relation containing the set values; i.e. `self`
377
+ #
378
+ # @raise [ActiveTriples::UndefinedPropertyError] if the property is not
379
+ # already an {RDF::Term} and is not defined in `#property_config`
380
+ #
381
+ # @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Statement For
382
+ # documentation on {RDF::Statement} and the handling of
383
+ # non-{RDF::Resource} values.
384
+ def set(values)
385
+ raise UndefinedPropertyError.new(property, reflections) if predicate.nil?
386
+
387
+ values = prepare_relation(values) if values.is_a?(Relation)
388
+ values = [values].compact unless values.kind_of?(Array)
389
+
390
+ clear
391
+ values.each { |val| set_value(val) }
392
+
393
+ parent.persist! if parent.persistence_strategy.is_a? ParentStrategy
394
+ self
395
+ end
396
+
397
+ ##
398
+ # @overload subtract(enum)
399
+ # Deletes objects in the enumerable from the relation
400
+ # @param values [Enumerable] an enumerable of objects to delete
401
+ # @overload subtract(*values)
402
+ # Deletes each argument value from the relation
403
+ # @param *values [Array<Object>] the objects to delete
404
+ #
405
+ # @return [Relation] self
406
+ #
407
+ # @note This casts symbols to a literals, which gets us symmetric behavior
408
+ # with `#set(:sym)`.
409
+ # @see #delete
410
+ def subtract(*values)
411
+ values = values.first if values.first.is_a? Enumerable
412
+ statements = values.map do |value|
413
+ value = RDF::Literal(value) if value.is_a? Symbol
414
+ [rdf_subject, predicate, value]
415
+ end
416
+
417
+ parent.delete(*statements)
418
+ self
419
+ end
420
+
421
+ ##
422
+ # Replaces the first argument with the second as a value within the
423
+ # relation.
424
+ #
425
+ # @param swap_out [Object] the value to delete
426
+ # @param swap_in [Object] the replacement value
427
+ #
428
+ # @return [Relation] self
429
+ def swap(swap_out, swap_in)
430
+ self.<<(swap_in) if delete?(swap_out)
339
431
  end
340
432
 
341
433
  protected
342
434
 
435
+ ##
436
+ # Converts an object to the appropriate class.
437
+ #
438
+ # Literals are cast only when the datatype is known.
439
+ #
440
+ # @private
441
+ def convert_object(value)
442
+ case value
443
+ when RDFSource
444
+ value
445
+ when RDF::Literal
446
+ if value.simple?
447
+ value.object
448
+ elsif value.has_datatype?
449
+ RDF::Literal.datatyped_class(value.datatype.to_s) ? value.object : value
450
+ else
451
+ value
452
+ end
453
+ when RDF::Resource
454
+ make_node(value)
455
+ else
456
+ value
457
+ end
458
+ end
459
+
460
+ ##
461
+ # @private
343
462
  def node_cache
344
463
  @node_cache ||= {}
345
464
  end
346
465
 
466
+ ##
467
+ # @private
468
+ def objects(&block)
469
+ solutions = parent.query(subject: rdf_subject, predicate: predicate)
470
+ solutions.extend(RDF::Enumerable) unless solutions.respond_to?(:each_object)
471
+
472
+ solutions.each_object(&block)
473
+ end
474
+
475
+ private
476
+ ##
477
+ # @private
347
478
  def is_property?
348
479
  reflections.has_property?(property) || is_type?
349
480
  end
350
481
 
482
+ ##
483
+ # @private
351
484
  def is_type?
352
485
  (property == RDF.type || property.to_s == "type") &&
353
486
  (!reflections.kind_of?(RDFSource) || !is_property?)
354
487
  end
355
488
 
489
+ ##
490
+ # @private
491
+ # @return [Hash<Symbol, ]
492
+ def property_config
493
+ return TYPE_PROPERTY if is_type?
494
+
495
+ reflections.reflect_on_property(property)
496
+ end
497
+
498
+ ##
499
+ # @private
356
500
  def set_value(val)
357
501
  resource = value_to_node(val.respond_to?(:resource) ? val.resource : val)
358
502
  if resource.kind_of? RDFSource
@@ -365,14 +509,24 @@ module ActiveTriples
365
509
  parent.insert [rdf_subject, predicate, resource]
366
510
  end
367
511
 
368
- def type_property
369
- { :predicate => RDF.type, :cast => false }
370
- end
371
-
512
+ ##
513
+ # @private
372
514
  def value_to_node(val)
373
515
  valid_datatype?(val) ? RDF::Literal(val) : val
374
516
  end
375
517
 
518
+ def prepare_relation(values)
519
+ values.objects.map do |value|
520
+ if value.respond_to?(:resource?) && value.resource?
521
+ values.convert_object(value)
522
+ else
523
+ value
524
+ end
525
+ end
526
+ end
527
+
528
+ ##
529
+ # @private
376
530
  def add_child_node(object, resource)
377
531
  parent.insert [rdf_subject, predicate, resource.rdf_subject]
378
532
  resource = resource.respond_to?(:resource) ? resource.resource : resource
@@ -384,12 +538,14 @@ module ActiveTriples
384
538
  parent.persistence_strategy.ancestors.find { |a| a == new_resource })
385
539
  new_resource.set_persistence_strategy(ParentStrategy)
386
540
  new_resource.parent = parent
541
+ new_resource.persist!
387
542
  end
388
543
 
389
544
  self.node_cache[resource.rdf_subject] = (resource == object ? new_resource : object)
390
- new_resource.persist! if new_resource.persistence_strategy.is_a? ParentStrategy
391
545
  end
392
546
 
547
+ ##
548
+ # @private
393
549
  def valid_datatype?(val)
394
550
  case val
395
551
  when String, Date, Time, Numeric, Symbol, TrueClass, FalseClass then true
@@ -397,48 +553,36 @@ module ActiveTriples
397
553
  end
398
554
  end
399
555
 
400
- # Converts an object to the appropriate class.
401
- def convert_object(value)
402
- case value
403
- when RDFSource
404
- value
405
- when RDF::Literal
406
- return_literals? ? value : value.object
407
- when RDF::Resource
408
- make_node(value)
409
- else
410
- value
411
- end
412
- end
413
-
414
556
  ##
415
557
  # Build a child resource or return it from this object's cache
416
558
  #
417
559
  # Builds the resource from the class_name specified for the
418
560
  # property.
561
+ #
562
+ # @private
419
563
  def make_node(value)
420
564
  return value unless cast?
421
565
  klass = class_for_value(value)
422
566
  value = RDF::Node.new if value.nil?
423
567
  node = node_cache[value] if node_cache[value]
424
568
  node ||= klass.from_uri(value,parent)
425
- node.set_persistence_strategy(property_config[:persist_to]) if
569
+ node.set_persistence_strategy(property_config[:persist_to]) if
426
570
  is_property? && property_config[:persist_to]
427
571
  return nil if (is_property? && property_config[:class_name]) && (class_for_value(value) != class_for_property)
428
572
  self.node_cache[value] ||= node
429
573
  node
430
574
  end
431
575
 
576
+ ##
577
+ # @private
432
578
  def cast?
433
579
  return true unless is_property? || (rel_args && rel_args[:cast])
434
580
  return rel_args[:cast] if rel_args.has_key?(:cast)
435
581
  !!property_config[:cast]
436
582
  end
437
583
 
438
- def return_literals?
439
- rel_args && rel_args[:literal]
440
- end
441
-
584
+ ##
585
+ # @private
442
586
  def final_parent
443
587
  @final_parent ||= begin
444
588
  parent = self.parent
@@ -450,16 +594,22 @@ module ActiveTriples
450
594
  end
451
595
  end
452
596
 
597
+ ##
598
+ # @private
453
599
  def class_for_value(v)
454
600
  uri_class(v) || class_for_property
455
601
  end
456
602
 
603
+ ##
604
+ # @private
457
605
  def uri_class(v)
458
- v = RDF::URI.new(v) if v.kind_of? String
606
+ v = RDF::URI.intern(v) if v.kind_of? String
459
607
  type_uri = parent.query([v, RDF.type, nil]).to_a.first.try(:object)
460
608
  Resource.type_registry[type_uri]
461
609
  end
462
610
 
611
+ ##
612
+ # @private
463
613
  def class_for_property
464
614
  klass = property_config[:class_name] if is_property?
465
615
  klass ||= Resource
@@ -469,6 +619,7 @@ module ActiveTriples
469
619
  end
470
620
 
471
621
  ##
622
+ # @private
472
623
  # @return [RDF::Term] the subject of the relation
473
624
  def rdf_subject
474
625
  if value_arguments.length < 1 || value_arguments.length > 2