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
@@ -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