active-triples 0.10.2 → 0.11.0

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 (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
@@ -24,7 +24,7 @@ module ActiveTriples
24
24
  # @return [Boolean] true if the resource was sucessfully destroyed
25
25
  def destroy(&block)
26
26
  yield if block_given?
27
-
27
+
28
28
  persist!
29
29
  @destroyed = true
30
30
  end
@@ -57,6 +57,19 @@ module ActiveTriples
57
57
  raise NotImplementedError, 'Abstract method #persist! is unimplemented'
58
58
  end
59
59
 
60
+ ##
61
+ # @param graph [RDF::Graph]
62
+ # @return [RDF::Graph]
63
+ def graph=(graph)
64
+ @graph = graph
65
+ end
66
+
67
+ ##
68
+ # @return [RDF::Graph]
69
+ def graph
70
+ @graph ||= RDF::Graph.new
71
+ end
72
+
60
73
  ##
61
74
  # @abstract Clear out any old assertions in the datastore / repository
62
75
  # about this node or statement thus preparing to receive the updated
@@ -8,10 +8,19 @@ module ActiveTriples
8
8
  #
9
9
  # Collaborates closely with ActiveTriples::Reflection
10
10
  #
11
- # Define properties at the class level with:
11
+ # @example define properties at the class level
12
12
  #
13
13
  # property :title, predicate: RDF::DC.title, class_name: ResourceClass
14
14
  #
15
+ # @example using property setters & getters
16
+ # resource.property :title, predicate: RDF::DC.title,
17
+ # class_name: ResourceClass
18
+ #
19
+ # resource.title = 'Comet in Moominland'
20
+ #
21
+ # resource.title # => ['Comet in Moominland']
22
+ # resource.title(literal: true) # => [RDF::Literal('Comet in Moominland')]
23
+ #
15
24
  # @see {ActiveTriples::Reflection}
16
25
  # @see {ActiveTriples::PropertyBuilder}
17
26
  module Properties
@@ -54,9 +63,15 @@ module ActiveTriples
54
63
  #
55
64
  # @return [Array<RDF::URI>]
56
65
  def unregistered_predicates
57
- preds = registered_predicates
58
- preds << RDF.type
59
- predicates.select { |p| !preds.include? p }
66
+ registered_preds = registered_predicates << RDF.type
67
+ unregistered_preds = []
68
+
69
+ query(subject: rdf_subject) do |stmt|
70
+ unregistered_preds << stmt.predicate unless
71
+ registered_preds.include? stmt.predicate
72
+ end
73
+
74
+ unregistered_preds
60
75
  end
61
76
 
62
77
  public
@@ -42,7 +42,7 @@ module ActiveTriples
42
42
  raise ArgumentError, "property names must be a Symbol" unless
43
43
  name.kind_of?(Symbol)
44
44
 
45
- options[:predicate] = RDF::URI.new(options[:predicate])
45
+ options[:predicate] = RDF::URI.intern(options[:predicate])
46
46
  raise ArgumentError, "must provide an RDF::URI to :predicate" unless
47
47
  options[:predicate].valid?
48
48
 
@@ -67,15 +67,15 @@ module ActiveTriples
67
67
  def self.define_readers(mixin, name)
68
68
  mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
69
69
  def #{name}(*args)
70
- get_values(:#{name})
70
+ get_values(:#{name}, *args)
71
71
  end
72
72
  CODE
73
73
  end
74
74
 
75
75
  def self.define_id_reader(mixin, name)
76
76
  mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
77
- def #{name}_ids(*args)
78
- get_values(:#{name}, :cast => false)
77
+ def #{name}_ids(*)
78
+ get_values(:#{name}, cast: false)
79
79
  end
80
80
  CODE
81
81
  end
@@ -75,8 +75,8 @@ module ActiveTriples
75
75
  define_model_callbacks :persist
76
76
  end
77
77
 
78
- delegate :query, :each, :load!, :count, :has_statement?, :to => :graph
79
- delegate :to_base, :term?, :escape, :to => :to_term
78
+ delegate :query, :each, :load!, :count, :has_statement?, to: :graph
79
+ delegate :to_base, :term?, :escape, to: :to_term
80
80
 
81
81
  ##
82
82
  # Initialize an instance of this resource class. Defaults to a
@@ -93,21 +93,19 @@ module ActiveTriples
93
93
  resource_uri = args.shift unless args.first.is_a?(Hash)
94
94
  @rdf_subject = get_uri(resource_uri) if resource_uri
95
95
 
96
- unless args.first.is_a?(Hash) || args.empty?
96
+ if args.first.is_a?(Hash) || args.empty?
97
+ set_persistence_strategy(RepositoryStrategy)
98
+ else
97
99
  set_persistence_strategy(ParentStrategy)
98
100
  persistence_strategy.parent = args.shift
99
- else
100
- set_persistence_strategy(RepositoryStrategy)
101
101
  end
102
102
 
103
- @graph = RDF::Graph.new(*args, &block)
103
+ persistence_strategy.graph = RDF::Graph.new(*args, &block)
104
104
  reload
105
105
 
106
106
  # Append type to graph if necessary.
107
107
  Array.wrap(self.class.type).each do |type|
108
- unless self.get_values(:type).include?(type)
109
- self.get_values(:type) << type
110
- end
108
+ get_values(:type) << type unless get_values(:type).include?(type)
111
109
  end
112
110
  end
113
111
 
@@ -128,12 +126,12 @@ module ActiveTriples
128
126
  ##
129
127
  # Gives a hash containing both the registered and unregistered attributes of
130
128
  # the resource. Unregistered attributes are given with full URIs.
131
- #
132
- # @example
129
+ #
130
+ # @example
133
131
  # class WithProperties
134
132
  # include ActiveTriples::RDFSource
135
133
  # property :title, predicate: RDF::Vocab::DC.title
136
- # property :creator, predicate: RDF::Vocab::DC.creator,
134
+ # property :creator, predicate: RDF::Vocab::DC.creator,
137
135
  # class_name: 'Agent'
138
136
  # end
139
137
  #
@@ -146,7 +144,7 @@ module ActiveTriples
146
144
  #
147
145
  # resource.creator.build
148
146
  # resource.title << ['Comet in Moominland', 'Christmas in Moominvalley']
149
-
147
+ #
150
148
  # resource.attributes
151
149
  # # => {"id"=>"g47123700054720",
152
150
  # # "title"=>["Comet in Moominland", "Christmas in Moominvalley"],
@@ -171,25 +169,33 @@ module ActiveTriples
171
169
  end
172
170
 
173
171
  def attributes=(values)
174
- raise ArgumentError, "values must be a Hash, you provided #{values.class}" unless values.kind_of? Hash
172
+ raise(ArgumentError, "values must be a Hash. Got: #{values.class}") unless
173
+ values.is_a? Hash
174
+
175
175
  values = values.with_indifferent_access
176
176
  id = values.delete(:id)
177
- set_subject!(id) if node?
177
+ set_subject!(id) if node? && id && get_uri(id).uri?
178
+
178
179
  values.each do |key, value|
179
180
  if reflections.has_property?(key)
180
- set_value(rdf_subject, key, value)
181
- elsif nested_attributes_options.keys.map { |k| "#{k}_attributes" }.include?(key)
181
+ set_value(key, value)
182
+ elsif nested_attributes_options
183
+ .keys.any? { |k| key == "#{k}_attributes" }
182
184
  send("#{key}=".to_sym, value)
183
185
  else
184
- raise ArgumentError, "No association found for name `#{key}'. Has it been defined yet?"
186
+ raise ArgumentError, "No association found for name `#{key}'. " \
187
+ 'Has it been defined yet?'
185
188
  end
186
189
  end
187
190
  end
188
191
 
189
- def serializable_hash(options = nil)
190
- attrs = (fields.map { |f| f.to_s }) << 'id'
191
- hash = super(:only => attrs)
192
+ ##
193
+ # @return [Hash]
194
+ def serializable_hash(*)
195
+ attrs = fields.map(&:to_s) << 'id'
196
+ hash = super(only: attrs)
192
197
  unregistered_predicates.map { |uri| hash[uri.to_s] = get_values(uri) }
198
+
193
199
  hash
194
200
  end
195
201
 
@@ -204,7 +210,7 @@ module ActiveTriples
204
210
  # @param args [Array<Object>]
205
211
  # @return [String]
206
212
  def dump(*args)
207
- if args.first == :jsonld and respond_to?(:jsonld_context)
213
+ if args.first == :jsonld && respond_to?(:jsonld_context)
208
214
  args << {} unless args.last.is_a?(Hash)
209
215
  args.last[:context] ||= jsonld_context
210
216
  end
@@ -214,17 +220,23 @@ module ActiveTriples
214
220
  ##
215
221
  # Delegate parent to the persistence strategy if possible
216
222
  #
217
- # @todo establish a better pattern for this. `#parent` has been a public
223
+ # @todo establish a better pattern for this. `#parent` has been a public
218
224
  # method in the past, but it's probably time to deprecate it.
219
225
  def parent
220
- persistence_strategy.respond_to?(:parent) ? persistence_strategy.parent : nil
226
+ return persistence_strategy.parent if
227
+ persistence_strategy.respond_to?(:parent)
228
+
229
+ nil
221
230
  end
222
231
 
223
232
  ##
224
233
  # @todo deprecate/remove
225
234
  # @see #parent
226
235
  def parent=(parent)
227
- persistence_strategy.respond_to?(:parent=) ? (persistence_strategy.parent = parent) : nil
236
+ return persistence_strategy.parent = parent if
237
+ persistence_strategy.respond_to?(:parent=)
238
+
239
+ nil
228
240
  end
229
241
 
230
242
  ##
@@ -237,15 +249,15 @@ module ActiveTriples
237
249
  def rdf_subject
238
250
  @rdf_subject ||= RDF::Node.new
239
251
  end
240
- alias_method :to_term, :rdf_subject
252
+ alias to_term rdf_subject
241
253
 
242
254
  ##
243
255
  # Returns `nil` as the `graph_name`. This behavior mimics an `RDF::Graph`
244
256
  # with no graph name, or one without named graph support.
245
257
  #
246
- # @note: it's possible to think of an `RDFSource` as "supporting named
258
+ # @note: it's possible to think of an `RDFSource` as "supporting named
247
259
  # graphs" in the sense that the `#rdf_subject` is an implied graph name.
248
- # For RDF.rb's purposes, however, it has a nil graph name: when
260
+ # For RDF.rb's purposes, however, it has a nil graph name: when
249
261
  # enumerating statements, we treat them as triples.
250
262
  #
251
263
  # @return [nil]
@@ -253,7 +265,7 @@ module ActiveTriples
253
265
  def graph_name
254
266
  nil
255
267
  end
256
-
268
+
257
269
  ##
258
270
  # @return [String] A string identifier for the resource; '' if the
259
271
  # resource is a node
@@ -299,12 +311,15 @@ module ActiveTriples
299
311
  end
300
312
 
301
313
  def type
302
- self.get_values(:type)
314
+ get_values(:type)
303
315
  end
304
316
 
305
317
  def type=(type)
306
- raise "Type must be an RDF::URI" unless type.kind_of? RDF::URI
307
- self.update(RDF::Statement.new(rdf_subject, RDF.type, type))
318
+ raise(ArgumentError,
319
+ "Type must be an RDF::URI. Got: #{type.class}, #{type}") unless
320
+ type.is_a? RDF::URI
321
+
322
+ update(RDF::Statement.new(rdf_subject, RDF.type, type))
308
323
  end
309
324
 
310
325
  ##
@@ -322,16 +337,6 @@ module ActiveTriples
322
337
  node? ? [] : [rdf_subject.to_s]
323
338
  end
324
339
 
325
- ##
326
- # @return [Array<RDF::URI>] a group of properties to use for default labels.
327
- def default_labels
328
- [RDF::SKOS.prefLabel,
329
- RDF::DC.title,
330
- RDF::RDFS.label,
331
- RDF::SKOS.altLabel,
332
- RDF::SKOS.hiddenLabel]
333
- end
334
-
335
340
  ##
336
341
  # Load data from the #rdf_subject URI. Retrieved data will be
337
342
  # parsed into the Resource's graph from available RDF::Readers
@@ -353,15 +358,15 @@ module ActiveTriples
353
358
  # @yieldparam [ActiveTriples::RDFSource] resource self
354
359
  #
355
360
  # @return [ActiveTriples::RDFSource] self
356
- def fetch(*args, &block)
361
+ def fetch(*args, &_block)
357
362
  begin
358
363
  load(rdf_subject, *args)
359
364
  rescue => e
360
365
  if block_given?
361
366
  yield(self)
362
367
  else
363
- raise "#{self} is a blank node; Cannot fetch a resource without a URI" if
364
- node?
368
+ raise "#{self} is a blank node; " \
369
+ 'Cannot fetch a resource without a URI' if node?
365
370
  raise e
366
371
  end
367
372
  end
@@ -404,12 +409,12 @@ module ActiveTriples
404
409
  #
405
410
  # @overload set_value(subject, property, values)
406
411
  # Updates the values for the property, using the given term as the subject
407
- #
408
- # @param [RDF::Term] subject the term representing the
412
+ #
413
+ # @param [RDF::Term] subject the term representing the
409
414
  # @param [RDF::Term, #to_sym] property a symbol with the property name
410
415
  # or an RDF::Term to use as a predicate.
411
416
  # @param [Array<RDF::Resource>, RDF::Resource] values an array of values
412
- # or a single value. If not an {RDF::Resource}, the values will be
417
+ # or a single value. If not an {RDF::Resource}, the values will be
413
418
  # coerced to an {RDF::Literal} or {RDF::Node} by {RDF::Statement}
414
419
  #
415
420
  # @return [ActiveTriples::Relation] an array {Relation} containing the
@@ -421,16 +426,17 @@ module ActiveTriples
421
426
  # @note This method will delete existing statements with the given
422
427
  # subject and predicate from the graph
423
428
  #
424
- # @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Statement For
425
- # documentation on {RDF::Statement} and the handling of
429
+ # @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Statement For
430
+ # documentation on {RDF::Statement} and the handling of
426
431
  # non-{RDF::Resource} values.
427
432
  def set_value(*args)
428
433
  # Add support for legacy 3-parameter syntax
429
434
  if args.length > 3 || args.length < 2
430
- raise ArgumentError, "wrong number of arguments (#{args.length} for 2-3)"
435
+ raise ArgumentError,
436
+ "wrong number of arguments (#{args.length} for 2-3)"
431
437
  end
432
438
  values = args.pop
433
- get_relation(args).set(values)
439
+ get_values(*args).set(values)
434
440
  end
435
441
 
436
442
  ##
@@ -442,7 +448,7 @@ module ActiveTriples
442
448
  # properties directly on this RDFSource, is:
443
449
  # get_values(property)
444
450
  #
445
- # @overload get_values(property)
451
+ # @overload get_values(property)
446
452
  # Gets values on the RDFSource for the given property
447
453
  # @param [String, #to_term] property the property for the values
448
454
  #
@@ -452,22 +458,25 @@ module ActiveTriples
452
458
  # @param [RDF::Term] uri the term to use as the subject
453
459
  # @param [String, #to_term] property the property for the values
454
460
  #
455
- # @return [ActiveTriples::Relation] an array {Relation} containing the
461
+ # @return [ActiveTriples::Relation] an array {Relation} containing the
456
462
  # values of the property
457
463
  #
458
- # @todo should this raise an error when the property argument is not an
464
+ # @todo should this raise an error when the property argument is not an
459
465
  # {RDF::Term} or a registered property key?
460
466
  def get_values(*args)
461
- get_relation(args)
467
+ @relation_cache ||= {}
468
+ rel = Relation.new(self, args)
469
+ @relation_cache["#{rel.send(:rdf_subject)}/#{rel.property}/#{rel.rel_args}"] ||= rel
470
+ @relation_cache["#{rel.send(:rdf_subject)}/#{rel.property}/#{rel.rel_args}"]
462
471
  end
463
472
 
464
473
  ##
465
474
  # Returns an array of values belonging to the property requested. Elements
466
475
  # in the array may RdfResource objects or a valid datatype.
467
- #
476
+ #
468
477
  # @param [RDF::Term, :to_s] term_or_property
469
478
  def [](term_or_property)
470
- get_relation([term_or_property])
479
+ get_values(term_or_property)
471
480
  end
472
481
 
473
482
  ##
@@ -475,23 +484,21 @@ module ActiveTriples
475
484
  #
476
485
  # @param [RDF::Term, :to_s] term_or_property
477
486
  # @param [Array<RDF::Resource>, RDF::Resource] values an array of values
478
- # or a single value to set the property to.
487
+ # or a single value to set the property to.
479
488
  #
480
- # @note This method will delete existing statements with the correct
489
+ # @note This method will delete existing statements with the correct
481
490
  # subject and predicate from the graph
482
491
  def []=(term_or_property, value)
483
492
  self[term_or_property].set(value)
484
493
  end
485
494
 
486
495
  ##
496
+ # @deprecated for removal in 1.0; use `#get_values` instead.
487
497
  # @see #get_values
488
- # @todo deprecate and remove? this is an alias to `#get_values`
489
498
  def get_relation(args)
490
- reload if (persistence_strategy.respond_to? :loaded?) && !persistence_strategy.loaded?
491
- @relation_cache ||= {}
492
- rel = Relation.new(self, args)
493
- @relation_cache["#{rel.send(:rdf_subject)}/#{rel.property}/#{rel.rel_args}"] ||= rel
494
- @relation_cache["#{rel.send(:rdf_subject)}/#{rel.property}/#{rel.rel_args}"]
499
+ warn 'DEPRECATION: `ActiveTriples::RDFSource#get_relation` will be' \
500
+ 'removed in 1.0; use `#get_values` instead.'
501
+ get_values(*args)
495
502
  end
496
503
 
497
504
  ##
@@ -508,13 +515,12 @@ module ActiveTriples
508
515
  # the param. Otherwise it creates a URI for the resource and
509
516
  # rebuilds the graph with the updated URI.
510
517
  def set_subject!(uri_or_str)
511
- raise "Refusing update URI when one is already assigned!" unless
518
+ raise 'Refusing to update URI when one is already assigned!' unless
512
519
  node? || rdf_subject == RDF::URI(nil)
513
-
514
- return false if uri_or_str.nil? ||
515
- (uri_or_str.to_s.empty? &&
516
- !uri_or_str.kind_of?(RDF::URI))
517
-
520
+
521
+ return if uri_or_str.nil? ||
522
+ (uri_or_str.to_s.empty? && !uri_or_str.is_a?(RDF::URI))
523
+
518
524
  new_subject = get_uri(uri_or_str)
519
525
  rewrite_statement_uris(rdf_subject, new_subject)
520
526
 
@@ -526,7 +532,7 @@ module ActiveTriples
526
532
  #
527
533
  # @return [Boolean]
528
534
  def new_record?
529
- not persisted?
535
+ !persisted?
530
536
  end
531
537
 
532
538
  def mark_for_destruction
@@ -539,126 +545,73 @@ module ActiveTriples
539
545
 
540
546
  private
541
547
 
542
- ##
543
- # This gives the {RDF::Graph} which represents the current state of this
544
- # resource.
545
- #
546
- # @return [RDF::Graph] the underlying graph representation of the
547
- # `RDFSource`.
548
- #
549
- # @see http://www.w3.org/TR/2014/REC-rdf11-concepts-20140225/#change-over-time
550
- # RDF Concepts and Abstract Syntax comment on "RDF source"
551
- def graph
552
- @graph
553
- end
554
-
555
- ##
556
-
557
- # Lists fields registered as properties on the object.
558
- #
559
- # @return [Array<Symbol>] the list of registered properties.
560
- def fields
561
- properties.keys.map(&:to_sym).reject{ |x| x == :type }
562
- end
548
+ ##
549
+ # @return [Array<RDF::URI>] a group of properties to use for default labels.
550
+ def default_labels
551
+ [RDF::Vocab::SKOS.prefLabel,
552
+ RDF::Vocab::DC.title,
553
+ RDF::RDFS.label,
554
+ RDF::Vocab::SKOS.altLabel,
555
+ RDF::Vocab::SKOS.hiddenLabel]
556
+ end
563
557
 
564
- ##
565
- # Returns the properties registered and their configurations.
566
- #
567
- # @return [ActiveSupport::HashWithIndifferentAccess{String => ActiveTriples::NodeConfig}]
568
- def properties
569
- _active_triples_config
570
- end
558
+ ##
559
+ # Rewrites the subject and object of each statement containing
560
+ # `old_subject` in either position. Used when setting the subject to
561
+ # remove the placeholder blank node subjects.
562
+ #
563
+ # @param [RDF::Term] old_subject
564
+ # @param [RDF::Term] new_subject
565
+ # @return [void]
566
+ def rewrite_statement_uris(old_subject, new_subject)
567
+ graph.query(subject: old_subject).each do |st|
568
+ graph.delete(st)
571
569
 
572
- ##
573
- # List of RDF predicates registered as properties on the object.
574
- #
575
- # @return [Array<RDF::URI>]
576
- def registered_predicates
577
- properties.values.map { |config| config.predicate }
570
+ st.subject = new_subject
571
+ st.object = new_subject if st.object == old_subject
572
+ graph.insert(st)
578
573
  end
579
574
 
580
- ##
581
- # List of RDF predicates used in the Resource's triples, but not
582
- # mapped to any property or accessor methods.
583
- #
584
- # @return [Array<RDF::URI>]
585
- def unregistered_predicates
586
- registered_preds = registered_predicates
587
- registered_preds << RDF.type
588
- unregistered_preds = []
589
-
590
- query(subject: rdf_subject) do |stmt|
591
- unregistered_preds << stmt.predicate unless
592
- registered_preds.include? stmt.predicate
593
- end
575
+ graph.query(object: old_subject).each do |st|
576
+ graph.delete(st)
594
577
 
595
- unregistered_preds
578
+ st.object = new_subject
579
+ graph.insert(st)
596
580
  end
581
+ end
597
582
 
598
- def default_labels
599
- [RDF::Vocab::SKOS.prefLabel,
600
- RDF::Vocab::DC.title,
601
- RDF::RDFS.label,
602
- RDF::Vocab::SKOS.altLabel,
603
- RDF::Vocab::SKOS.hiddenLabel]
604
- end
583
+ ##
584
+ # Takes a URI or String and aggressively tries to convert it into
585
+ # an RDF term. If a String is given, first tries to interpret it
586
+ # as a valid URI, then tries to append it to base_uri. Finally,
587
+ # raises an error if no valid term can be built.
588
+ #
589
+ # The argument must be an RDF::Node, an object that responds to
590
+ # #to_uri, a String that represents a valid URI, or a String that
591
+ # appends to the Resource's base_uri to create a valid URI.
592
+ #
593
+ # @TODO: URI.scheme_list is naive and incomplete. Find a better
594
+ # way to check for an existing scheme.
595
+ #
596
+ # @param uri_or_str [RDF::Resource, String]
597
+ #
598
+ # @return [RDF::Resource] A term
599
+ # @raise [RuntimeError] no valid RDF term could be built
600
+ def get_uri(uri_or_str)
601
+ return uri_or_str.to_term if uri_or_str.respond_to? :to_term
605
602
 
606
- ##
607
- # Rewrites the subject and object of each statement containing
608
- # `old_subject` in either position. Used when setting the subject to
609
- # remove the placeholder blank node subjects.
610
- #
611
- # @param [RDF::Term] old_subject
612
- # @param [RDF::Term] new_subject
613
- # @return [void]
614
- def rewrite_statement_uris(old_subject, new_subject)
615
- graph.transaction(mutable: true) do |tx|
616
- tx.query(subject: old_subject).each do |st|
617
- tx.delete(st)
618
-
619
- st.subject = new_subject
620
- st.object = new_subject if st.object == old_subject
621
- tx.insert(st)
622
- end
623
-
624
- tx.query(object: old_subject).each do |st|
625
- tx.delete(st)
626
-
627
- st.object = new_subject
628
- tx.insert(st)
629
- end
630
- end
631
- end
603
+ uri_or_node = RDF::Resource.new(uri_or_str)
604
+ return uri_or_node if uri_or_node.valid?
632
605
 
633
- ##
634
- # Takes a URI or String and aggressively tries to convert it into
635
- # an RDF term. If a String is given, first tries to interpret it
636
- # as a valid URI, then tries to append it to base_uri. Finally,
637
- # raises an error if no valid term can be built.
638
- #
639
- # The argument must be an RDF::Node, an object that responds to
640
- # #to_uri, a String that represents a valid URI, or a String that
641
- # appends to the Resource's base_uri to create a valid URI.
642
- #
643
- # @TODO: URI.scheme_list is naive and incomplete. Find a better
644
- # way to check for an existing scheme.
645
- #
646
- # @param uri_or_str [RDF::Resource, String]
647
- #
648
- # @return [RDF::Resource] A term
649
- # @raise [RuntimeError] no valid RDF term could be built
650
- def get_uri(uri_or_str)
651
- return uri_or_str.to_term if uri_or_str.respond_to? :to_term
652
- return uri_or_str if uri_or_str.is_a? RDF::Node
653
- uri_or_node = RDF::Resource.new(uri_or_str)
654
- return uri_or_node if uri_or_node.valid?
655
- uri_or_str = uri_or_str.to_s
656
- return RDF::URI(base_uri.to_s) / uri_or_str if base_uri && !uri_or_str.start_with?(base_uri.to_s)
657
- raise RuntimeError, "could not make a valid RDF::URI from #{uri_or_str}"
658
- end
606
+ uri_or_str = uri_or_str.to_s
607
+ return RDF::URI.intern(base_uri.to_s) / uri_or_str if
608
+ base_uri && !uri_or_str.start_with?(base_uri.to_s)
659
609
 
660
- public
610
+ raise "could not make a valid RDF::URI from #{uri_or_str}"
611
+ end
661
612
 
613
+ ##
614
+ # Class methods for RDFSource, included via ActiveSupport
662
615
  module ClassMethods
663
616
  ##
664
617
  # Adapter for a consistent interface for creating a new Resource
@@ -679,10 +632,8 @@ module ActiveTriples
679
632
  # @param [ActiveTriples::Schema, #properties] schema A schema to apply.
680
633
  # @param [#apply!] strategy A strategy for applying. Defaults
681
634
  # to ActiveTriples::ExtensionStrategy
682
- def apply_schema(schema, strategy=ActiveTriples::ExtensionStrategy)
683
- schema.properties.each do |property|
684
- strategy.apply(self, property)
685
- end
635
+ def apply_schema(schema, strategy = ActiveTriples::ExtensionStrategy)
636
+ schema.properties.each { |property| strategy.apply(self, property) }
686
637
  end
687
638
 
688
639
  ##
@@ -697,7 +648,8 @@ module ActiveTriples
697
648
  # persisted, false will be returned presenting
698
649
  # a window of opportunity for an ID clash.
699
650
  def id_persisted?(test_id)
700
- rdf_subject = self.new(test_id).rdf_subject
651
+ rdf_subject = new(test_id).rdf_subject
652
+
701
653
  ActiveTriples::Repositories.has_subject?(rdf_subject)
702
654
  end
703
655
 
@@ -713,8 +665,9 @@ module ActiveTriples
713
665
  # persisted, false will be returned presenting
714
666
  # a window of opportunity for an ID clash.
715
667
  def uri_persisted?(test_uri)
716
- rdf_subject = test_uri.kind_of?(RDF::URI) ? test_uri : RDF::URI(test_uri)
717
- ActiveTriples::Repositories.has_subject?(rdf_subject)
668
+ test_uri = RDF::URI.intern(test_uri) unless test_uri.is_a?(RDF::URI)
669
+
670
+ ActiveTriples::Repositories.has_subject?(test_uri)
718
671
  end
719
672
  end
720
673
  end