active-fedora 1.2.2 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|