active-fedora 1.2.2 → 1.2.3
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.
- data/History.txt +30 -0
- data/NG_XML_DATASTREAM.textile +25 -0
- data/VERSION +1 -1
- data/active-fedora.gemspec +3 -2
- data/lib/active_fedora.rb +16 -13
- data/lib/active_fedora/base.rb +212 -22
- data/lib/active_fedora/metadata_datastream.rb +8 -2
- data/lib/active_fedora/metadata_datastream_helper.rb +10 -7
- data/lib/active_fedora/nokogiri_datastream.rb +5 -0
- data/lib/active_fedora/rels_ext_datastream.rb +9 -0
- data/lib/active_fedora/semantic_node.rb +253 -40
- data/lib/fedora/connection.rb +13 -12
- data/lib/fedora/repository.rb +3 -1
- data/spec/unit/base_extra_spec.rb +1 -1
- data/spec/unit/base_file_management_spec.rb +25 -9
- data/spec/unit/metadata_datastream_spec.rb +6 -0
- data/spec/unit/repository_spec.rb +7 -0
- data/spec/unit/semantic_node_spec.rb +44 -0
- data/spec/unit/solr_config_options_spec.rb +1 -1
- metadata +5 -4
@@ -46,11 +46,17 @@ module ActiveFedora
|
|
46
46
|
##FIX this bug, it should delete it from a copy of params in case passed to another datastream for update since this will modify params
|
47
47
|
##for subsequent calls if updating more than one datastream in a single update_indexed_attributes call
|
48
48
|
current_params = params.clone
|
49
|
-
# remove any fields from params that this datastream doesn't recognize
|
50
|
-
current_params.delete_if {|field_name,new_values| !self.fields.include?(field_name.to_sym) }
|
51
49
|
|
50
|
+
# remove any fields from params that this datastream doesn't recognize
|
51
|
+
current_params.delete_if do |field_name,new_values|
|
52
|
+
if field_name.kind_of?(Array) then field_name = field_name.first end
|
53
|
+
!self.fields.include?(field_name.to_sym)
|
54
|
+
end
|
55
|
+
|
52
56
|
result = current_params.dup
|
53
57
|
current_params.each do |field_name,new_values|
|
58
|
+
if field_name.kind_of?(Array) then field_name = field_name.first end
|
59
|
+
|
54
60
|
##FIX this bug, it should delete it from a copy of params in case passed to another datastream for update
|
55
61
|
#if field does not exist just skip it
|
56
62
|
next if !self.fields.include?(field_name.to_sym)
|
@@ -50,6 +50,16 @@ module ActiveFedora::MetadataDatastreamHelper
|
|
50
50
|
return solr_doc
|
51
51
|
end
|
52
52
|
|
53
|
+
# ** EXPERIMENTAL **
|
54
|
+
#
|
55
|
+
# This is utilized by ActiveFedora::Base.load_instance_from_solr to set
|
56
|
+
# metadata values in this object using the Solr document passed in.
|
57
|
+
# Any keys in the solr document that map to a metadata field key within a MetadataDatastream object
|
58
|
+
# are set to the corresponding value. Any others are ignored. Solrizer::FieldNameMapper.solr_name
|
59
|
+
# is used to map solr key to field key name.
|
60
|
+
#
|
61
|
+
# ====Warning
|
62
|
+
# Solr must be synchronized with data in Fedora.
|
53
63
|
def from_solr(solr_doc)
|
54
64
|
fields.each do |field_key, field_info|
|
55
65
|
field_symbol = Solrizer::FieldNameMapper.solr_name(field_key, field_info[:type])
|
@@ -85,12 +95,5 @@ module ActiveFedora::MetadataDatastreamHelper
|
|
85
95
|
end
|
86
96
|
return builder.to_xml
|
87
97
|
end
|
88
|
-
|
89
|
-
|
90
|
-
# protected
|
91
|
-
#
|
92
|
-
# def generate_solr_symbol(field_name, field_type) # :nodoc:
|
93
|
-
# solr_name(field_name, field_type)
|
94
|
-
# end
|
95
98
|
|
96
99
|
end
|
@@ -84,6 +84,11 @@ class ActiveFedora::NokogiriDatastream < ActiveFedora::Datastream
|
|
84
84
|
#do nothing for now
|
85
85
|
end
|
86
86
|
|
87
|
+
#overriding this method just so metadatahelper method does not get called
|
88
|
+
def from_solr(solr_doc)
|
89
|
+
#do nothing for now
|
90
|
+
end
|
91
|
+
|
87
92
|
def solrize_accessor(accessor_name, accessor_info, opts={})
|
88
93
|
solr_doc = opts.fetch(:solr_doc, Solr::Document.new)
|
89
94
|
parents = opts.fetch(:parents, [])
|
@@ -54,6 +54,15 @@ module ActiveFedora
|
|
54
54
|
return solr_doc
|
55
55
|
end
|
56
56
|
|
57
|
+
# ** EXPERIMENTAL **
|
58
|
+
#
|
59
|
+
# This is utilized by ActiveFedora::Base.load_instance_from_solr to load
|
60
|
+
# the relationships hash using the Solr document passed in instead of from the RELS-EXT datastream
|
61
|
+
# in Fedora. Utilizes Solrizer::FieldNameMapper.solr_name to map solr key to
|
62
|
+
# relationship predicate.
|
63
|
+
#
|
64
|
+
# ====Warning
|
65
|
+
# Solr must be synchronized with RELS-EXT data in Fedora.
|
57
66
|
def from_solr(solr_doc)
|
58
67
|
#cycle through all possible predicates
|
59
68
|
PREDICATE_MAPPINGS.keys.each do |predicate|
|
@@ -63,19 +63,34 @@ module ActiveFedora
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
+
# ** EXPERIMENTAL **
|
67
|
+
#
|
68
|
+
# Internal method that ensures a relationship subject such as :self and :inbound
|
69
|
+
# exist within the named_relationships_desc hash tracking named relationships metadata.
|
70
|
+
# This method just calls the class method counterpart of this method.
|
66
71
|
def register_named_subject(subject)
|
67
72
|
self.class.register_named_subject(subject)
|
68
73
|
end
|
69
74
|
|
75
|
+
# ** EXPERIMENTAL **
|
76
|
+
#
|
77
|
+
# Internal method that adds relationship name and predicate pair to either an outbound (:self)
|
78
|
+
# or inbound (:inbound) relationship types. This method just calls the class method counterpart of this method.
|
70
79
|
def register_named_relationship(subject, name, predicate, opts)
|
71
80
|
self.class.register_named_relationship(subject, name, predicate, opts)
|
72
81
|
end
|
73
|
-
|
82
|
+
|
83
|
+
# ** EXPERIMENTAL **
|
84
|
+
#
|
85
|
+
# Remove the given ActiveFedora::Relationship from this object
|
74
86
|
def remove_relationship(relationship)
|
75
87
|
@relationships_are_dirty = true
|
76
88
|
unregister_triple(relationship.subject, relationship.predicate, relationship.object)
|
77
89
|
end
|
78
90
|
|
91
|
+
# ** EXPERIMENTAL **
|
92
|
+
#
|
93
|
+
# Remove the subject, predicate, and object triple from the relationships hash
|
79
94
|
def unregister_triple(subject, predicate, object)
|
80
95
|
if relationship_exists?(subject, predicate, object)
|
81
96
|
relationships[subject][predicate].delete_if {|curObj| curObj == object}
|
@@ -85,6 +100,9 @@ module ActiveFedora
|
|
85
100
|
end
|
86
101
|
end
|
87
102
|
|
103
|
+
# ** EXPERIMENTAL **
|
104
|
+
#
|
105
|
+
# Returns true if a relationship exists for the given subject, predicate, and object triple
|
88
106
|
def relationship_exists?(subject, predicate, object)
|
89
107
|
outbound_only = (subject != :inbound)
|
90
108
|
#cache the call in case it is retrieving inbound as well, don't want to hit solr too many times
|
@@ -138,6 +156,9 @@ module ActiveFedora
|
|
138
156
|
return rels
|
139
157
|
end
|
140
158
|
|
159
|
+
# ** EXPERIMENTAL **
|
160
|
+
#
|
161
|
+
# Return array of objects for a given relationship name
|
141
162
|
def named_relationship(name)
|
142
163
|
rels = nil
|
143
164
|
if inbound_relationship_names.include?(name)
|
@@ -149,6 +170,13 @@ module ActiveFedora
|
|
149
170
|
return rels
|
150
171
|
end
|
151
172
|
|
173
|
+
# ** EXPERIMENTAL **
|
174
|
+
#
|
175
|
+
# Gets the named relationships hash of subject=>name=>object_array
|
176
|
+
# It has an optional parameter of outbound_only that defaults true.
|
177
|
+
# If false it will include inbound relationships in the results.
|
178
|
+
# Also, it will only reload outbound relationships if the relationships hash has changed
|
179
|
+
# since the last time this method was called.
|
152
180
|
def named_relationships(outbound_only=true)
|
153
181
|
#make sure to update if relationships have been updated
|
154
182
|
if @relationships_are_dirty == true
|
@@ -161,6 +189,10 @@ module ActiveFedora
|
|
161
189
|
outbound_only ? @named_relationships : @named_relationships.merge(:inbound=>named_inbound_relationships)
|
162
190
|
end
|
163
191
|
|
192
|
+
# ** EXPERIMENTAL **
|
193
|
+
#
|
194
|
+
# Gets named relationships from the class using the current relationships hash
|
195
|
+
# and relationship name,predicate pairs.
|
164
196
|
def named_relationships_from_class()
|
165
197
|
rels = {}
|
166
198
|
named_relationship_predicates.each_pair do |subj, names|
|
@@ -174,6 +206,11 @@ module ActiveFedora
|
|
174
206
|
return rels
|
175
207
|
end
|
176
208
|
|
209
|
+
# ** EXPERIMENTAL **
|
210
|
+
#
|
211
|
+
# Return hash of named_relationships defined within other objects' RELS-EXT
|
212
|
+
# It returns a hash of relationship name to arrays of objects. It requeries
|
213
|
+
# solr each time this method is called.
|
177
214
|
def named_inbound_relationships
|
178
215
|
rels = {}
|
179
216
|
if named_relationships_desc.has_key?(:inbound)&&!named_relationships_desc[:inbound].empty?()
|
@@ -188,18 +225,30 @@ module ActiveFedora
|
|
188
225
|
return rels
|
189
226
|
end
|
190
227
|
|
228
|
+
# ** EXPERIMENTAL **
|
229
|
+
#
|
230
|
+
# Return hash of outbound relationship names and predicate pairs
|
191
231
|
def outbound_named_relationship_predicates
|
192
232
|
named_relationship_predicates.has_key?(:self) ? named_relationship_predicates[:self] : {}
|
193
233
|
end
|
194
234
|
|
235
|
+
# ** EXPERIMENTAL **
|
236
|
+
#
|
237
|
+
# Return hash of inbound relationship names and predicate pairs
|
195
238
|
def inbound_named_relationship_predicates
|
196
239
|
named_relationship_predicates.has_key?(:inbound) ? named_relationship_predicates[:inbound] : {}
|
197
240
|
end
|
198
241
|
|
242
|
+
# ** EXPERIMENTAL **
|
243
|
+
#
|
244
|
+
# Return hash of relationship names and predicate pairs
|
199
245
|
def named_relationship_predicates
|
200
246
|
@named_relationship_predicates ||= named_relationship_predicates_from_class
|
201
247
|
end
|
202
248
|
|
249
|
+
# ** EXPERIMENTAL **
|
250
|
+
#
|
251
|
+
# Return hash of relationship names and predicate pairs from class
|
203
252
|
def named_relationship_predicates_from_class
|
204
253
|
rels = {}
|
205
254
|
named_relationships_desc.each_pair do |subj, names|
|
@@ -211,6 +260,9 @@ module ActiveFedora
|
|
211
260
|
return rels
|
212
261
|
end
|
213
262
|
|
263
|
+
# ** EXPERIMENTAL **
|
264
|
+
#
|
265
|
+
# Return array all relationship names
|
214
266
|
def relationship_names
|
215
267
|
names = []
|
216
268
|
named_relationships_desc.each_key do |subject|
|
@@ -219,18 +271,34 @@ module ActiveFedora
|
|
219
271
|
names
|
220
272
|
end
|
221
273
|
|
274
|
+
# ** EXPERIMENTAL **
|
275
|
+
#
|
276
|
+
# Return array of relationship names for all named inbound relationships (coming from other objects' RELS-EXT and Solr)
|
222
277
|
def inbound_relationship_names
|
223
278
|
named_relationships_desc.has_key?(:inbound) ? named_relationships_desc[:inbound].keys : []
|
224
279
|
end
|
225
280
|
|
281
|
+
# ** EXPERIMENTAL **
|
282
|
+
#
|
283
|
+
# Return array of relationship names for all named outbound relationships (coming from this object's RELS-EXT)
|
226
284
|
def outbound_relationship_names
|
227
285
|
named_relationships_desc.has_key?(:self) ? named_relationships_desc[:self].keys : []
|
228
286
|
end
|
229
287
|
|
288
|
+
# ** EXPERIMENTAL **
|
289
|
+
#
|
290
|
+
# Return hash of named_relationships defined within this object's RELS-EXT
|
291
|
+
# It returns a hash of relationship name to arrays of objects
|
230
292
|
def named_outbound_relationships
|
231
293
|
named_relationships_desc.has_key?(:self) ? named_relationships[:self] : {}
|
232
294
|
end
|
233
295
|
|
296
|
+
# ** EXPERIMENTAL **
|
297
|
+
#
|
298
|
+
# Returns true if the given relationship name is a named relationship
|
299
|
+
# ====Parameters
|
300
|
+
# name: Name of relationship
|
301
|
+
# outbound_only: If false checks inbound relationships as well (defaults to true)
|
234
302
|
def is_named_relationship?(name, outbound_only=true)
|
235
303
|
if outbound_only
|
236
304
|
outbound_relationship_names.include?(name)
|
@@ -239,14 +307,30 @@ module ActiveFedora
|
|
239
307
|
end
|
240
308
|
end
|
241
309
|
|
310
|
+
# ** EXPERIMENTAL **
|
311
|
+
#
|
312
|
+
# Return hash that stores named relationship metadata defined by has_relationship calls
|
313
|
+
# ====Example
|
314
|
+
# For the following relationship
|
315
|
+
#
|
316
|
+
# has_relationship "audio_records", :has_part, :type=>AudioRecord
|
317
|
+
# Results in the following returned by named_relationships_desc
|
318
|
+
# {:self=>{"audio_records"=>{:type=>AudioRecord, :singular=>nil, :predicate=>:has_part, :inbound=>false}}}
|
242
319
|
def named_relationships_desc
|
243
320
|
@named_relationships_desc ||= named_relationships_desc_from_class
|
244
321
|
end
|
245
322
|
|
323
|
+
# ** EXPERIMENTAL **
|
324
|
+
#
|
325
|
+
# Get class instance variable named_relationships_desc that holds has_relationship metadata
|
246
326
|
def named_relationships_desc_from_class
|
247
327
|
self.class.named_relationships_desc
|
248
328
|
end
|
249
329
|
|
330
|
+
# ** EXPERIMENTAL **
|
331
|
+
#
|
332
|
+
# Return the value of :type for the relationship for name passed in.
|
333
|
+
# It defaults to ActiveFedora::Base.
|
250
334
|
def named_relationship_type(name)
|
251
335
|
if is_named_relationship?(name,true)
|
252
336
|
subject = outbound_relationship_names.include?(name)? :self : :inbound
|
@@ -257,6 +341,10 @@ module ActiveFedora
|
|
257
341
|
return nil
|
258
342
|
end
|
259
343
|
|
344
|
+
# ** EXPERIMENTAL **
|
345
|
+
#
|
346
|
+
# Add an outbound relationship for given named relationship
|
347
|
+
# See ActiveFedora::SemanticNode::ClassMethods.has_relationship
|
260
348
|
def add_named_relationship(name, object)
|
261
349
|
if is_named_relationship?(name,true)
|
262
350
|
if named_relationships_desc[:self][name].has_key?(:type)
|
@@ -273,6 +361,9 @@ module ActiveFedora
|
|
273
361
|
end
|
274
362
|
end
|
275
363
|
|
364
|
+
# ** EXPERIMENTAL **
|
365
|
+
#
|
366
|
+
# Remove an object from the named relationship
|
276
367
|
def remove_named_relationship(name, object)
|
277
368
|
if is_named_relationship?(name,true)
|
278
369
|
remove_relationship(outbound_named_relationship_predicates[name],object)
|
@@ -281,23 +372,25 @@ module ActiveFedora
|
|
281
372
|
end
|
282
373
|
end
|
283
374
|
|
375
|
+
# ** EXPERIMENTAL **
|
376
|
+
#
|
377
|
+
# Throws an assertion error if kind_of_model? returns false for object and model_class
|
378
|
+
# ====Parameters
|
379
|
+
# name: Name of object (just label for output)
|
380
|
+
# object: The object to test
|
381
|
+
# model_class: The model class used to in kind_of_model? check on object
|
284
382
|
def assert_kind_of_model(name, object, model_class)
|
285
383
|
raise "Assertion failure: #{name}: #{object.pid} does not have model #{model_class}, it has model #{relationships[:self][:has_model]}" unless object.kind_of_model?(model_class)
|
286
384
|
end
|
287
385
|
|
288
|
-
|
289
|
-
#
|
290
|
-
#
|
291
|
-
#
|
292
|
-
#
|
293
|
-
#
|
294
|
-
# This
|
295
|
-
#
|
296
|
-
# object type or not.
|
297
|
-
#
|
298
|
-
# If hasmodel does not match than this will return false indicated it does not
|
299
|
-
# have the correct model.
|
300
|
-
############################################################################
|
386
|
+
# ** EXPERIMENTAL **
|
387
|
+
#
|
388
|
+
# Checks that this object is matches the model class passed in.
|
389
|
+
# It requires two steps to pass to return true
|
390
|
+
# 1. It has a hasModel relationship of the same model
|
391
|
+
# 2. kind_of? returns true for the model passed in
|
392
|
+
# This method can most often be used to detect if an object from Fedora that was created
|
393
|
+
# with a different model was then used to populate this object.
|
301
394
|
def kind_of_model?(model_class)
|
302
395
|
if self.kind_of?(model_class)
|
303
396
|
#check has model and class match
|
@@ -342,33 +435,56 @@ module ActiveFedora
|
|
342
435
|
# puts "=> and whose outbound relationships are #{self.outbound_relationships.inspect}"
|
343
436
|
self.outbound_relationships.each do |predicate, targets_array|
|
344
437
|
targets_array.each do |target|
|
345
|
-
|
346
|
-
|
438
|
+
xmlns=String.new
|
439
|
+
case predicate
|
440
|
+
when :has_model, "hasModel", :hasModel
|
441
|
+
xmlns="info:fedora/fedora-system:def/model#"
|
442
|
+
else
|
443
|
+
xmlns="info:fedora/fedora-system:def/relations-external#"
|
444
|
+
end
|
445
|
+
# puts ". #{predicate} #{target} #{xmlns}"
|
446
|
+
xml.root.elements["rdf:Description"].add_element(self.class.predicate_lookup(predicate), {"xmlns" => "#{xmlns}", "rdf:resource"=>target})
|
347
447
|
end
|
348
448
|
end
|
349
449
|
xml.to_s
|
350
450
|
end
|
351
451
|
|
352
452
|
module ClassMethods
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
453
|
+
|
454
|
+
# Allows for a relationship to be treated like any other attribute of a model class. You define
|
455
|
+
# named relationships in your model class using this method. You then have access to several
|
456
|
+
# helper methods to list, append, and remove objects from the list of relationships.
|
457
|
+
# ====Examples to define two relationships
|
458
|
+
# class AudioRecord < ActiveFedora::Base
|
459
|
+
#
|
460
|
+
# has_relationship "oral_history", :has_part, :inbound=>true, :type=>OralHistory
|
461
|
+
# has_relationship "similar_audio", :has_part, :type=>AudioRecord
|
462
|
+
#
|
463
|
+
# The first two parameters are required:
|
464
|
+
# name: relationship name
|
465
|
+
# predicate: predicate for the relationship
|
466
|
+
# opts:
|
467
|
+
# possible parameters
|
468
|
+
# :inbound => if true loads an external relationship via Solr (defaults to false)
|
469
|
+
# :type => The type of model to use when instantiated an object from the pid in this relationship (defaults to ActiveFedora::Base)
|
470
|
+
#
|
471
|
+
# If inbound is true it expects the relationship to be defined by another object's RELS-EXT
|
472
|
+
# and to load that relationship from Solr. Otherwise, if inbound is true the relationship is stored in
|
473
|
+
# this object's RELS-EXT datastream
|
474
|
+
#
|
475
|
+
# Word of caution - The same predicate may not be used twice for two inbound or two outbound relationships. However, it may be used twice if one is inbound
|
476
|
+
# and one is outbound as shown in the example above. A full list of possible predicates are defined by PREDICATE_MAPPINGS
|
477
|
+
#
|
478
|
+
# For the oral_history relationship in the example above the following helper methods are created:
|
479
|
+
# oral_history: returns array of OralHistory objects that have this AudioRecord with predicate :has_part
|
480
|
+
# oral_history_ids: Return array of pids for OralHistory objects that have this AudioRecord with predicate :has_part
|
481
|
+
#
|
482
|
+
# For the outbound relationship "similar_audio" there are two additional methods to append and remove objects from that relationship
|
483
|
+
# since it is managed internally:
|
484
|
+
# similar_audio: Return array of AudioRecord objects that have been added to similar_audio relationship
|
485
|
+
# similar_audio_ids: Return array of AudioRecord object pids that have been added to similar_audio relationship
|
486
|
+
# similar_audio_append: Add an AudioRecord object to the similar_audio relationship
|
487
|
+
# similar_audio_remove: Remove an AudioRecord from the similar_audio relationship
|
372
488
|
def has_relationship(name, predicate, opts = {})
|
373
489
|
opts = {:singular => nil, :inbound => false}.merge(opts)
|
374
490
|
if opts[:inbound] == true
|
@@ -385,7 +501,32 @@ module ActiveFedora
|
|
385
501
|
end
|
386
502
|
end
|
387
503
|
|
388
|
-
#
|
504
|
+
# Generates relationship finders for predicates that point in both directions
|
505
|
+
#
|
506
|
+
# @name Name of the relationship method(s) to create
|
507
|
+
# @outbound_predicate Predicate used in outbound relationships
|
508
|
+
# @inbound_predicate Predicate used in inbound relationships
|
509
|
+
# @opts
|
510
|
+
#
|
511
|
+
# Example:
|
512
|
+
# has_bidirectional_relationship("parts", :has_part, :is_part_of)
|
513
|
+
#
|
514
|
+
# will create three instance methods: parts_outbound, and parts_inbound and parts
|
515
|
+
# the inbound and outbound methods are the same that would result from calling
|
516
|
+
# create_inbound_relationship_finders and create_outbound_relationship_finders
|
517
|
+
# The third method combines the results of both and handles generating appropriate
|
518
|
+
# solr queries where necessary.
|
519
|
+
def has_bidirectional_relationship(name, outbound_predicate, inbound_predicate, opts={})
|
520
|
+
create_bidirectional_relationship_finders(name, outbound_predicate, inbound_predicate, opts)
|
521
|
+
end
|
522
|
+
|
523
|
+
# ** EXPERIMENTAL **
|
524
|
+
#
|
525
|
+
# Check to make sure a subject,name, and predicate triple does not already exist
|
526
|
+
# with the same subject but different name.
|
527
|
+
# This method is used to ensure conflicting has_relationship calls are not made because
|
528
|
+
# predicates cannot be reused across relationship names. Otherwise, the mapping of relationship name
|
529
|
+
# to predicate in RELS-EXT would be broken.
|
389
530
|
def named_predicate_exists_with_different_name?(subject,name,predicate)
|
390
531
|
if named_relationships_desc.has_key?(subject)
|
391
532
|
named_relationships_desc[subject].each_pair do |existing_name, args|
|
@@ -394,24 +535,51 @@ module ActiveFedora
|
|
394
535
|
end
|
395
536
|
return false
|
396
537
|
end
|
397
|
-
|
398
|
-
#
|
538
|
+
|
539
|
+
# ** EXPERIMENTAL **
|
540
|
+
#
|
541
|
+
# Return hash that stores named relationship metadata defined by has_relationship calls
|
542
|
+
# ====Example
|
543
|
+
# For the following relationship
|
544
|
+
#
|
545
|
+
# has_relationship "audio_records", :has_part, :type=>AudioRecord
|
546
|
+
# Results in the following returned by named_relationships_desc
|
547
|
+
# {:self=>{"audio_records"=>{:type=>AudioRecord, :singular=>nil, :predicate=>:has_part, :inbound=>false}}}
|
399
548
|
def named_relationships_desc
|
400
549
|
@class_named_relationships_desc ||= Hash[:self => {}]
|
401
550
|
end
|
402
|
-
|
551
|
+
|
552
|
+
# ** EXPERIMENTAL **
|
553
|
+
#
|
554
|
+
# Internal method that ensures a relationship subject such as :self and :inbound
|
555
|
+
# exist within the named_relationships_desc hash tracking named relationships metadata.
|
403
556
|
def register_named_subject(subject)
|
404
557
|
unless named_relationships_desc.has_key?(subject)
|
405
558
|
named_relationships_desc[subject] = {}
|
406
559
|
end
|
407
560
|
end
|
408
561
|
|
562
|
+
# ** EXPERIMENTAL **
|
563
|
+
#
|
564
|
+
# Internal method that adds relationship name and predicate pair to either an outbound (:self)
|
565
|
+
# or inbound (:inbound) relationship types.
|
409
566
|
def register_named_relationship(subject, name, predicate, opts)
|
410
567
|
register_named_subject(subject)
|
411
568
|
opts.merge!({:predicate=>predicate})
|
412
569
|
named_relationships_desc[subject][name] = opts
|
413
570
|
end
|
414
|
-
|
571
|
+
|
572
|
+
# ** EXPERIMENTAL **
|
573
|
+
#
|
574
|
+
# Used in has_relationship call to create dynamic helper methods to
|
575
|
+
# append and remove objects to and from a named relationship
|
576
|
+
# ====Example
|
577
|
+
# For the following relationship
|
578
|
+
#
|
579
|
+
# has_relationship "audio_records", :has_part, :type=>AudioRecord
|
580
|
+
#
|
581
|
+
# Methods audio_records_append and audio_records_remove are created.
|
582
|
+
# Boths methods take an object that is kind_of? ActiveFedora::Base as a parameter
|
415
583
|
def create_named_relationship_methods(name)
|
416
584
|
append_method_name = "#{name.to_s.downcase}_append"
|
417
585
|
remove_method_name = "#{name.to_s.downcase}_remove"
|
@@ -480,6 +648,51 @@ module ActiveFedora
|
|
480
648
|
end
|
481
649
|
END
|
482
650
|
end
|
651
|
+
|
652
|
+
# Generates relationship finders for predicates that point in both directions
|
653
|
+
#
|
654
|
+
# @name Name of the relationship method(s) to create
|
655
|
+
# @outbound_predicate Predicate used in outbound relationships
|
656
|
+
# @inbound_predicate Predicate used in inbound relationships
|
657
|
+
# @opts
|
658
|
+
#
|
659
|
+
def create_bidirectional_relationship_finders(name, outbound_predicate, inbound_predicate, opts={})
|
660
|
+
inbound_method_name = name.to_s+"_inbound"
|
661
|
+
outbound_method_name = name.to_s+"_outbound"
|
662
|
+
create_outbound_relationship_finders(outbound_method_name, outbound_predicate, opts)
|
663
|
+
create_inbound_relationship_finders(inbound_method_name, inbound_predicate, opts)
|
664
|
+
|
665
|
+
class_eval <<-END
|
666
|
+
def #{name}(opts={})
|
667
|
+
if opts[:response_format] == :solr || opts[:response_format] == :load_from_solr
|
668
|
+
escaped_uri = self.internal_uri.gsub(/(:)/, '\\:')
|
669
|
+
query = "#{inbound_predicate}_s:\#{escaped_uri}"
|
670
|
+
|
671
|
+
outbound_id_array = #{outbound_method_name}(:response_format=>:id_array)
|
672
|
+
query = query + " OR " + ActiveFedora::SolrService.construct_query_for_pids(outbound_id_array)
|
673
|
+
|
674
|
+
solr_result = SolrService.instance.conn.query(query)
|
675
|
+
|
676
|
+
if opts[:response_format] == :solr
|
677
|
+
return solr_result
|
678
|
+
elsif opts[:response_format] == :load_from_solr || self.load_from_solr
|
679
|
+
return ActiveFedora::SolrService.reify_solr_results(solr_result,{:load_from_solr=>true})
|
680
|
+
else
|
681
|
+
return ActiveFedora::SolrService.reify_solr_results(solr_result)
|
682
|
+
end
|
683
|
+
else
|
684
|
+
ary = #{inbound_method_name}(opts) + #{outbound_method_name}(opts)
|
685
|
+
return ary.uniq
|
686
|
+
end
|
687
|
+
end
|
688
|
+
def #{name}_ids
|
689
|
+
#{name}(:response_format => :id_array)
|
690
|
+
end
|
691
|
+
def #{name}_from_solr
|
692
|
+
#{name}(:response_format => :load_from_solr)
|
693
|
+
end
|
694
|
+
END
|
695
|
+
end
|
483
696
|
|
484
697
|
# relationships are tracked as a hash of structure {subject => {predicate => [object]}}
|
485
698
|
def relationships
|