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.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/CHANGES.md +17 -11
- data/README.md +72 -39
- data/lib/active_triples/configurable.rb +6 -1
- data/lib/active_triples/list.rb +1 -4
- data/lib/active_triples/nested_attributes.rb +10 -7
- data/lib/active_triples/persistable.rb +13 -0
- data/lib/active_triples/persistence_strategies/parent_strategy.rb +47 -34
- data/lib/active_triples/persistence_strategies/persistence_strategy.rb +14 -1
- data/lib/active_triples/properties.rb +19 -4
- data/lib/active_triples/property_builder.rb +4 -4
- data/lib/active_triples/rdf_source.rb +142 -189
- data/lib/active_triples/relation.rb +307 -156
- data/lib/active_triples/util/buffered_transaction.rb +126 -0
- data/lib/active_triples/util/extended_bounded_description.rb +75 -0
- data/lib/active_triples/version.rb +1 -1
- data/spec/active_triples/configurable_spec.rb +35 -7
- data/spec/active_triples/identifiable_spec.rb +19 -6
- data/spec/active_triples/list_spec.rb +15 -7
- data/spec/active_triples/nested_attributes_spec.rb +12 -10
- data/spec/active_triples/persistable_spec.rb +0 -4
- data/spec/active_triples/persistence_strategies/parent_strategy_spec.rb +57 -10
- data/spec/active_triples/rdf_source_spec.rb +137 -97
- data/spec/active_triples/relation_spec.rb +436 -132
- data/spec/active_triples/resource_spec.rb +8 -23
- data/spec/active_triples/util/buffered_transaction_spec.rb +187 -0
- data/spec/active_triples/util/extended_bounded_description_spec.rb +98 -0
- data/spec/integration/reciprocal_properties_spec.rb +10 -10
- data/spec/support/matchers.rb +13 -1
- 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
|
-
#
|
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
|
-
|
58
|
-
|
59
|
-
|
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.
|
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(*
|
78
|
-
get_values(:#{name}, :
|
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?, :
|
79
|
-
delegate :to_base, :term?, :escape, :
|
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
|
-
|
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
|
-
|
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
|
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
|
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(
|
181
|
-
elsif nested_attributes_options
|
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}'.
|
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
|
-
|
190
|
-
|
191
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
314
|
+
get_values(:type)
|
303
315
|
end
|
304
316
|
|
305
317
|
def type=(type)
|
306
|
-
raise
|
307
|
-
|
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, &
|
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;
|
364
|
-
|
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,
|
435
|
+
raise ArgumentError,
|
436
|
+
"wrong number of arguments (#{args.length} for 2-3)"
|
431
437
|
end
|
432
438
|
values = args.pop
|
433
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
491
|
-
|
492
|
-
|
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
|
518
|
+
raise 'Refusing to update URI when one is already assigned!' unless
|
512
519
|
node? || rdf_subject == RDF::URI(nil)
|
513
|
-
|
514
|
-
return
|
515
|
-
|
516
|
-
|
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
|
-
|
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
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
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
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
578
|
+
st.object = new_subject
|
579
|
+
graph.insert(st)
|
596
580
|
end
|
581
|
+
end
|
597
582
|
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
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
|
-
|
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
|
-
|
635
|
-
|
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
|
-
|
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
|
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 =
|
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
|
-
|
717
|
-
|
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
|