active-fedora 6.8.0 → 7.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +15 -5
- data/CONTRIBUTING.md +2 -0
- data/Gemfile +0 -2
- data/History.txt +2 -32
- data/README.md +143 -0
- data/Rakefile +5 -7
- data/active-fedora.gemspec +9 -9
- data/gemfiles/rails3.gemfile +11 -0
- data/gemfiles/rails4.gemfile +10 -0
- data/lib/active_fedora.rb +31 -4
- data/lib/active_fedora/association_relation.rb +18 -0
- data/lib/active_fedora/associations.rb +38 -171
- data/lib/active_fedora/associations/association.rb +163 -0
- data/lib/active_fedora/associations/association_scope.rb +39 -0
- data/lib/active_fedora/associations/belongs_to_association.rb +47 -25
- data/lib/active_fedora/associations/builder/association.rb +55 -0
- data/lib/active_fedora/associations/builder/belongs_to.rb +100 -0
- data/lib/active_fedora/associations/builder/collection_association.rb +56 -0
- data/lib/active_fedora/associations/builder/has_and_belongs_to_many.rb +30 -0
- data/lib/active_fedora/associations/builder/has_many.rb +63 -0
- data/lib/active_fedora/associations/builder/singular_association.rb +32 -0
- data/lib/active_fedora/associations/{association_collection.rb → collection_association.rb} +203 -53
- data/lib/active_fedora/associations/collection_proxy.rb +862 -0
- data/lib/active_fedora/associations/has_and_belongs_to_many_association.rb +35 -25
- data/lib/active_fedora/associations/has_many_association.rb +36 -11
- data/lib/active_fedora/associations/singular_association.rb +62 -0
- data/lib/active_fedora/attributes.rb +43 -139
- data/lib/active_fedora/autosave_association.rb +317 -0
- data/lib/active_fedora/base.rb +10 -327
- data/lib/active_fedora/callbacks.rb +1 -3
- data/lib/active_fedora/content_model.rb +16 -0
- data/lib/active_fedora/core.rb +151 -0
- data/lib/active_fedora/datastream_attribute.rb +76 -0
- data/lib/active_fedora/datastream_hash.rb +8 -13
- data/lib/active_fedora/datastreams.rb +39 -26
- data/lib/active_fedora/digital_object.rb +2 -2
- data/lib/active_fedora/fedora_attributes.rb +45 -0
- data/lib/active_fedora/fixture_loader.rb +1 -1
- data/lib/active_fedora/indexing.rb +6 -1
- data/lib/active_fedora/model.rb +0 -17
- data/lib/active_fedora/nested_attributes.rb +2 -2
- data/lib/active_fedora/null_relation.rb +7 -0
- data/lib/active_fedora/om_datastream.rb +3 -4
- data/lib/active_fedora/persistence.rb +41 -29
- data/lib/active_fedora/querying.rb +2 -163
- data/lib/active_fedora/rdf.rb +1 -0
- data/lib/active_fedora/rdf/indexing.rb +67 -0
- data/lib/active_fedora/rdf_datastream.rb +2 -50
- data/lib/active_fedora/rdf_node.rb +12 -7
- data/lib/active_fedora/rdf_node/term_proxy.rb +30 -21
- data/lib/active_fedora/rdfxml_rdf_datastream.rb +1 -1
- data/lib/active_fedora/reflection.rb +163 -20
- data/lib/active_fedora/relation.rb +33 -130
- data/lib/active_fedora/relation/calculations.rb +19 -0
- data/lib/active_fedora/relation/delegation.rb +22 -0
- data/lib/active_fedora/relation/finder_methods.rb +247 -0
- data/lib/active_fedora/relation/merger.rb +22 -0
- data/lib/active_fedora/relation/query_methods.rb +58 -0
- data/lib/active_fedora/relation/spawn_methods.rb +46 -0
- data/lib/active_fedora/relationship_graph.rb +0 -2
- data/lib/active_fedora/rels_ext_datastream.rb +1 -4
- data/lib/active_fedora/rubydora_connection.rb +1 -1
- data/lib/active_fedora/scoping.rb +20 -0
- data/lib/active_fedora/scoping/default.rb +38 -0
- data/lib/active_fedora/scoping/named.rb +32 -0
- data/lib/active_fedora/semantic_node.rb +54 -106
- data/lib/active_fedora/serialization.rb +19 -0
- data/lib/active_fedora/sharding.rb +58 -0
- data/lib/active_fedora/solr_digital_object.rb +15 -5
- data/lib/active_fedora/solr_instance_loader.rb +1 -1
- data/lib/active_fedora/solr_service.rb +1 -1
- data/lib/active_fedora/unsaved_digital_object.rb +6 -4
- data/lib/active_fedora/version.rb +1 -1
- data/lib/tasks/active_fedora.rake +3 -0
- data/lib/tasks/active_fedora_dev.rake +6 -5
- data/spec/config_helper.rb +14 -14
- data/spec/integration/associations_spec.rb +168 -455
- data/spec/integration/attributes_spec.rb +12 -11
- data/spec/integration/auditable_spec.rb +11 -11
- data/spec/integration/autosave_association_spec.rb +25 -0
- data/spec/integration/base_spec.rb +163 -163
- data/spec/integration/belongs_to_association_spec.rb +166 -0
- data/spec/integration/bug_spec.rb +7 -7
- data/spec/integration/collection_association_spec.rb +58 -0
- data/spec/integration/complex_rdf_datastream_spec.rb +88 -88
- data/spec/integration/datastream_collections_spec.rb +69 -69
- data/spec/integration/datastream_spec.rb +43 -43
- data/spec/integration/datastreams_spec.rb +63 -63
- data/spec/integration/delete_all_spec.rb +46 -39
- data/spec/integration/fedora_solr_sync_spec.rb +5 -5
- data/spec/integration/field_to_solr_name_spec.rb +34 -0
- data/spec/integration/full_featured_model_spec.rb +100 -101
- data/spec/integration/has_and_belongs_to_many_associations_spec.rb +341 -0
- data/spec/integration/has_many_associations_spec.rb +172 -24
- data/spec/integration/json_serialization_spec.rb +31 -0
- data/spec/integration/load_from_solr_spec.rb +48 -0
- data/spec/integration/model_spec.rb +35 -40
- data/spec/integration/nested_attribute_spec.rb +42 -43
- data/spec/integration/ntriples_datastream_spec.rb +131 -113
- data/spec/integration/om_datastream_spec.rb +67 -67
- data/spec/integration/persistence_spec.rb +7 -7
- data/spec/integration/rdf_nested_attributes_spec.rb +56 -56
- data/spec/integration/relation_delegation_spec.rb +26 -25
- data/spec/integration/relation_spec.rb +42 -0
- data/spec/integration/rels_ext_datastream_spec.rb +20 -20
- data/spec/integration/scoped_query_spec.rb +61 -51
- data/spec/integration/solr_instance_loader_spec.rb +5 -5
- data/spec/integration/solr_service_spec.rb +46 -46
- data/spec/samples/hydra-mods_article_datastream.rb +334 -334
- data/spec/samples/hydra-rights_metadata_datastream.rb +57 -57
- data/spec/samples/marpa-dc_datastream.rb +17 -17
- data/spec/samples/models/audio_record.rb +16 -16
- data/spec/samples/models/image.rb +2 -2
- data/spec/samples/models/mods_article.rb +5 -5
- data/spec/samples/models/oral_history.rb +18 -18
- data/spec/samples/models/seminar.rb +24 -24
- data/spec/samples/models/seminar_audio_file.rb +17 -17
- data/spec/samples/oral_history_sample_model.rb +21 -21
- data/spec/samples/special_thing.rb +14 -14
- data/spec/spec_helper.rb +11 -7
- data/spec/support/an_active_model.rb +2 -8
- data/spec/support/freeze_mocks.rb +12 -0
- data/spec/support/mock_fedora.rb +17 -16
- data/spec/unit/active_fedora_spec.rb +58 -60
- data/spec/unit/attributes_spec.rb +314 -0
- data/spec/unit/base_active_model_spec.rb +28 -27
- data/spec/unit/base_cma_spec.rb +5 -5
- data/spec/unit/base_datastream_management_spec.rb +27 -27
- data/spec/unit/base_extra_spec.rb +76 -48
- data/spec/unit/base_spec.rb +277 -348
- data/spec/unit/callback_spec.rb +18 -19
- data/spec/unit/code_configurator_spec.rb +17 -17
- data/spec/unit/config_spec.rb +8 -16
- data/spec/unit/content_model_spec.rb +79 -60
- data/spec/unit/datastream_collections_spec.rb +229 -229
- data/spec/unit/datastream_spec.rb +51 -63
- data/spec/unit/datastreams_spec.rb +87 -87
- data/spec/unit/file_configurator_spec.rb +217 -217
- data/spec/unit/has_and_belongs_to_many_collection_spec.rb +44 -25
- data/spec/unit/has_many_collection_spec.rb +26 -8
- data/spec/unit/inheritance_spec.rb +13 -12
- data/spec/unit/model_spec.rb +39 -45
- data/spec/unit/nom_datastream_spec.rb +15 -15
- data/spec/unit/ntriples_datastream_spec.rb +123 -118
- data/spec/unit/om_datastream_spec.rb +227 -233
- data/spec/unit/persistence_spec.rb +34 -15
- data/spec/unit/predicates_spec.rb +73 -73
- data/spec/unit/property_spec.rb +17 -9
- data/spec/unit/qualified_dublin_core_datastream_spec.rb +33 -33
- data/spec/unit/query_spec.rb +222 -198
- data/spec/unit/rdf_datastream_spec.rb +21 -28
- data/spec/unit/rdf_list_nested_attributes_spec.rb +34 -34
- data/spec/unit/rdf_list_spec.rb +65 -64
- data/spec/unit/rdf_node_spec.rb +7 -7
- data/spec/unit/rdf_xml_writer_spec.rb +10 -10
- data/spec/unit/rdfxml_rdf_datastream_spec.rb +27 -27
- data/spec/unit/relationship_graph_spec.rb +51 -51
- data/spec/unit/rels_ext_datastream_spec.rb +68 -74
- data/spec/unit/rspec_matchers/belong_to_associated_active_fedora_object_matcher_spec.rb +15 -15
- data/spec/unit/rspec_matchers/have_many_associated_active_fedora_objects_matcher_spec.rb +15 -15
- data/spec/unit/rspec_matchers/have_predicate_matcher_spec.rb +15 -15
- data/spec/unit/rspec_matchers/match_fedora_datastream_matcher_spec.rb +12 -12
- data/spec/unit/rubydora_connection_spec.rb +5 -5
- data/spec/unit/semantic_node_spec.rb +48 -107
- data/spec/unit/serializers_spec.rb +4 -4
- data/spec/unit/service_definitions_spec.rb +26 -26
- data/spec/unit/simple_datastream_spec.rb +17 -17
- data/spec/unit/solr_config_options_spec.rb +29 -28
- data/spec/unit/solr_digital_object_spec.rb +17 -25
- data/spec/unit/solr_service_spec.rb +95 -82
- data/spec/unit/unsaved_digital_object_spec.rb +24 -23
- data/spec/unit/validations_spec.rb +21 -21
- metadata +110 -159
- data/.rspec +0 -1
- data/.rubocop.yml +0 -1
- data/.rubocop_todo.yml +0 -938
- data/CONSOLE_GETTING_STARTED.textile +0 -1
- data/NOKOGIRI_DATASTREAMS.textile +0 -1
- data/README.textile +0 -116
- data/lib/active_fedora/associations/association_proxy.rb +0 -178
- data/lib/active_fedora/delegating.rb +0 -72
- data/lib/active_fedora/nokogiri_datastream.rb +0 -11
- data/spec/integration/delegating_spec.rb +0 -59
- data/spec/rails3_test_app/.gitignore +0 -4
- data/spec/rails3_test_app/.rspec +0 -1
- data/spec/rails3_test_app/Gemfile +0 -40
- data/spec/rails3_test_app/Rakefile +0 -7
- data/spec/rails3_test_app/app/controllers/application_controller.rb +0 -3
- data/spec/rails3_test_app/app/helpers/application_helper.rb +0 -2
- data/spec/rails3_test_app/app/views/layouts/application.html.erb +0 -14
- data/spec/rails3_test_app/config.ru +0 -4
- data/spec/rails3_test_app/config/application.rb +0 -42
- data/spec/rails3_test_app/config/boot.rb +0 -6
- data/spec/rails3_test_app/config/database.yml +0 -22
- data/spec/rails3_test_app/config/environment.rb +0 -5
- data/spec/rails3_test_app/config/environments/development.rb +0 -25
- data/spec/rails3_test_app/config/environments/production.rb +0 -49
- data/spec/rails3_test_app/config/environments/test.rb +0 -35
- data/spec/rails3_test_app/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/rails3_test_app/config/initializers/inflections.rb +0 -10
- data/spec/rails3_test_app/config/initializers/mime_types.rb +0 -5
- data/spec/rails3_test_app/config/initializers/secret_token.rb +0 -7
- data/spec/rails3_test_app/config/initializers/session_store.rb +0 -8
- data/spec/rails3_test_app/config/locales/en.yml +0 -5
- data/spec/rails3_test_app/config/routes.rb +0 -58
- data/spec/rails3_test_app/db/seeds.rb +0 -7
- data/spec/rails3_test_app/run_tests +0 -3
- data/spec/rails3_test_app/script/rails +0 -6
- data/spec/rails3_test_app/spec/spec_helper.rb +0 -27
- data/spec/rails3_test_app/spec/unit/rails_3_init.rb +0 -15
- data/spec/unit/association_proxy_spec.rb +0 -12
- data/spec/unit/base_delegate_spec.rb +0 -197
- data/spec/unit/base_delegate_to_spec.rb +0 -73
@@ -0,0 +1,20 @@
|
|
1
|
+
module ActiveFedora
|
2
|
+
module Scoping
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
include Default
|
6
|
+
include Named
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def current_scope #:nodoc:
|
12
|
+
Thread.current["#{self}_current_scope"]
|
13
|
+
end
|
14
|
+
|
15
|
+
def current_scope=(scope) #:nodoc:
|
16
|
+
Thread.current["#{self}_current_scope"] = scope
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module ActiveFedora
|
2
|
+
module Scoping
|
3
|
+
module Default
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
# Returns a scope for the model without the +default_scope+.
|
8
|
+
#
|
9
|
+
# class Post < ActiveRecord::Base
|
10
|
+
# def self.default_scope
|
11
|
+
# where published: true
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# Post.all # Fires "SELECT * FROM posts WHERE published = true"
|
16
|
+
# Post.unscoped.all # Fires "SELECT * FROM posts"
|
17
|
+
#
|
18
|
+
# This method also accepts a block. All queries inside the block will
|
19
|
+
# not use the +default_scope+:
|
20
|
+
#
|
21
|
+
# Post.unscoped {
|
22
|
+
# Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10"
|
23
|
+
# }
|
24
|
+
#
|
25
|
+
# It is recommended that you use the block form of unscoped because
|
26
|
+
# chaining unscoped with +scope+ does not work. Assuming that
|
27
|
+
# +published+ is a +scope+, the following two statements
|
28
|
+
# are equal: the +default_scope+ is applied on both.
|
29
|
+
#
|
30
|
+
# Post.unscoped.published
|
31
|
+
# Post.published
|
32
|
+
def unscoped
|
33
|
+
block_given? ? relation.scoping { yield } : relation
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module ActiveFedora
|
2
|
+
# = Active Fedora \Named \Scopes
|
3
|
+
module Scoping
|
4
|
+
module Named
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
# Returns an <tt>ActiveFedora::Relation</tt> scope object.
|
9
|
+
#
|
10
|
+
# posts = Post.all
|
11
|
+
# posts.size # Fires "select count(*) from posts" and returns the count
|
12
|
+
# posts.each {|p| puts p.name } # Fires "select * from posts" and loads post objects
|
13
|
+
#
|
14
|
+
# fruits = Fruit.all
|
15
|
+
# fruits = fruits.where(color: 'red') if options[:red_only]
|
16
|
+
# fruits = fruits.limit(10) if limited?
|
17
|
+
#
|
18
|
+
# You can define a scope that applies to all finders using
|
19
|
+
# <tt>ActiveRecord::Base.default_scope</tt>.
|
20
|
+
def all
|
21
|
+
if current_scope
|
22
|
+
current_scope.clone
|
23
|
+
else
|
24
|
+
scope = relation
|
25
|
+
scope.default_scoped = true
|
26
|
+
scope
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,15 +1,20 @@
|
|
1
1
|
module ActiveFedora
|
2
2
|
module SemanticNode
|
3
3
|
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
attr_accessor :
|
4
|
+
extend Deprecation
|
5
|
+
|
6
|
+
attr_accessor :relationships_loaded
|
7
|
+
attr_accessor :load_from_solr, :subject
|
8
8
|
|
9
9
|
def assert_kind_of(n, o,t)
|
10
10
|
raise "Assertion failure: #{n}: #{o} is not of type #{t}" unless o.kind_of?(t)
|
11
11
|
end
|
12
12
|
|
13
|
+
def clear_relationships
|
14
|
+
@relationships_loaded = false
|
15
|
+
@object_relations = nil
|
16
|
+
end
|
17
|
+
|
13
18
|
def object_relations
|
14
19
|
load_relationships if !relationships_loaded
|
15
20
|
@object_relations ||= RelationshipGraph.new
|
@@ -23,9 +28,11 @@ module ActiveFedora
|
|
23
28
|
end
|
24
29
|
|
25
30
|
# Add a relationship to the Object.
|
26
|
-
# @param
|
27
|
-
# @param target Either a string URI or an object that is a kind of ActiveFedora::Base
|
31
|
+
# @param [Symbol, String] predicate
|
32
|
+
# @param [URI, ActiveFedora::Base] target Either a string URI or an object that is a kind of ActiveFedora::Base
|
33
|
+
# TODO is target ever a AF::Base anymore?
|
28
34
|
def add_relationship(predicate, target, literal=false)
|
35
|
+
#raise ArgumentError, "predicate must be a symbol. You provided `#{predicate.inspect}'" unless predicate.class.in?([Symbol, String])
|
29
36
|
object_relations.add(predicate, target, literal)
|
30
37
|
rels_ext.content_will_change! if object_relations.dirty
|
31
38
|
end
|
@@ -77,45 +84,21 @@ module ActiveFedora
|
|
77
84
|
rels_ext.content_will_change!
|
78
85
|
end
|
79
86
|
|
80
|
-
def inbound_relationships(response_format=:uri)
|
81
|
-
rel_values = {}
|
82
|
-
inbound_relationship_predicates.each_pair do |name,predicate|
|
83
|
-
objects = self.send("#{name}",{:response_format=>response_format})
|
84
|
-
items = []
|
85
|
-
objects.each do |object|
|
86
|
-
if (response_format == :uri)
|
87
|
-
#inbound relationships are always object properties
|
88
|
-
items.push(object.internal_uri)
|
89
|
-
else
|
90
|
-
items.push(object)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
unless items.empty?
|
94
|
-
rel_values.merge!({predicate=>items})
|
95
|
-
end
|
96
|
-
end
|
97
|
-
return rel_values
|
98
|
-
end
|
99
|
-
|
100
|
-
def outbound_relationships()
|
101
|
-
relationships.statements
|
102
|
-
end
|
103
|
-
|
104
87
|
# If no arguments are supplied, return the whole RDF::Graph.
|
105
88
|
# if a predicate is supplied as a parameter, then it returns the result of quering the graph with that predicate
|
106
89
|
def relationships(*args)
|
107
|
-
load_relationships
|
90
|
+
load_relationships unless relationships_loaded
|
108
91
|
|
109
92
|
if args.empty?
|
110
93
|
raise "Must have internal_uri" unless internal_uri
|
111
94
|
return object_relations.to_graph(internal_uri)
|
112
95
|
end
|
113
96
|
rels = object_relations[args.first] || []
|
114
|
-
rels.map {|o| o.respond_to?(:internal_uri) ? o.internal_uri : o } #TODO, could just return the object
|
97
|
+
rels.map {|o| o.respond_to?(:internal_uri) ? o.internal_uri : o }.compact #TODO, could just return the object
|
115
98
|
end
|
116
99
|
|
117
100
|
def load_relationships
|
118
|
-
|
101
|
+
@relationships_loaded = true
|
119
102
|
content = rels_ext.content
|
120
103
|
return unless content.present?
|
121
104
|
RelsExtDatastream.from_xml content, rels_ext
|
@@ -124,90 +107,55 @@ module ActiveFedora
|
|
124
107
|
def ids_for_outbound(predicate)
|
125
108
|
(object_relations[predicate] || []).map do |o|
|
126
109
|
o = o.to_s if o.kind_of? RDF::Literal
|
127
|
-
o.kind_of?(String) ?
|
110
|
+
o.kind_of?(String) ? self.class.pid_from_uri(o) : o.pid
|
128
111
|
end
|
129
112
|
end
|
130
113
|
|
131
|
-
#
|
132
|
-
|
133
|
-
|
134
|
-
#
|
135
|
-
# has_relationship "audio_records", :has_part, :type=>AudioRecord
|
136
|
-
#
|
137
|
-
# Results in the following returned by relationships_desc
|
138
|
-
# {:self=>{"audio_records"=>{:type=>AudioRecord, :singular=>nil, :predicate=>:has_part, :inbound=>false}}}
|
139
|
-
def relationships_desc
|
140
|
-
@relationships_desc ||= self.class.relationships_desc
|
114
|
+
# @returns [String] the internal fedora URI
|
115
|
+
def internal_uri
|
116
|
+
self.class.internal_uri(pid)
|
141
117
|
end
|
142
118
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
@relationship_predicates[subj][name] = args[:predicate]
|
119
|
+
module ClassMethods
|
120
|
+
# @param [String,Array] uris a single uri (as a string) or a list of uris to convert to pids
|
121
|
+
# @returns [String] the pid component of the URI
|
122
|
+
def pids_from_uris(uris)
|
123
|
+
Deprecation.warn(SemanticNode, "pids_from_uris has been deprecated and will be removed in active-fedora 8.0.0", caller)
|
124
|
+
if uris.kind_of? String
|
125
|
+
pid_from_uri(uris)
|
126
|
+
else
|
127
|
+
Array(uris).map {|uri| pid_from_uri(uri)}
|
153
128
|
end
|
154
129
|
end
|
155
|
-
@relationship_predicates
|
156
|
-
end
|
157
|
-
|
158
|
-
# Return hash of outbound relationship names and predicate pairs
|
159
|
-
# @return [Hash] A hash of outbound relationship names mapped to predicates used
|
160
|
-
def outbound_relationship_predicates
|
161
|
-
relationship_predicates.has_key?(:self) ? relationship_predicates[:self] : {}
|
162
|
-
end
|
163
130
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
131
|
+
# Returns a suitable uri object for :has_model
|
132
|
+
# Should reverse Model#from_class_uri
|
133
|
+
def to_class_uri(attrs = {})
|
134
|
+
if self.respond_to? :pid_suffix
|
135
|
+
pid_suffix = self.pid_suffix
|
136
|
+
else
|
137
|
+
pid_suffix = attrs.fetch(:pid_suffix, ContentModel::CMODEL_PID_SUFFIX)
|
138
|
+
end
|
139
|
+
if self.respond_to? :pid_namespace
|
140
|
+
namespace = self.pid_namespace
|
141
|
+
else
|
142
|
+
namespace = attrs.fetch(:namespace, ContentModel::CMODEL_NAMESPACE)
|
143
|
+
end
|
144
|
+
"info:fedora/#{namespace}:#{ContentModel.sanitized_class_name(self)}#{pid_suffix}"
|
145
|
+
end
|
169
146
|
|
147
|
+
# @param [String] pid the fedora object identifier
|
148
|
+
# @returns [String] a URI represented as a string
|
149
|
+
def internal_uri(pid)
|
150
|
+
"info:fedora/#{pid}"
|
151
|
+
end
|
170
152
|
|
171
|
-
|
172
|
-
#
|
173
|
-
|
174
|
-
|
175
|
-
# ancestors.
|
176
|
-
# @return [Hash] Hash of relationship subject (:self or :inbound) mapped to nested hashs of each relationship name mapped to another hash relationship options
|
177
|
-
# @example
|
178
|
-
# For the following relationship
|
179
|
-
#
|
180
|
-
# has_relationship "audio_records", :has_part, :type=>AudioRecord
|
181
|
-
#
|
182
|
-
# Results in the following returned by relationships_desc
|
183
|
-
# {:self=>{"audio_records"=>{:type=>AudioRecord, :singular=>nil, :predicate=>:has_part, :inbound=>false}}}
|
184
|
-
def relationships_desc
|
185
|
-
#get any relationship descriptions from superclasses
|
186
|
-
if @class_relationships_desc.nil?
|
187
|
-
@class_relationships_desc ||= Hash[:self => {}]
|
188
|
-
|
189
|
-
#get super classes
|
190
|
-
super_klasses = []
|
191
|
-
#insert in reverse order so the child overwrites anything in parent
|
192
|
-
super_klass = self.superclass
|
193
|
-
while !super_klass.nil?
|
194
|
-
super_klasses.insert(0,super_klass)
|
195
|
-
super_klass = super_klass.superclass
|
196
|
-
end
|
197
|
-
|
198
|
-
super_klasses.each do |super_klass|
|
199
|
-
if super_klass.respond_to?(:relationships_desc)
|
200
|
-
super_rels = super_klass.relationships_desc
|
201
|
-
super_rels.each_pair do |subject,rels|
|
202
|
-
@class_relationships_desc[subject] = {} unless @class_relationships_desc.has_key?(subject)
|
203
|
-
@class_relationships_desc[subject].merge!(rels)
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
end
|
208
|
-
@class_relationships_desc
|
153
|
+
# @param [String] uri a uri (as a string)
|
154
|
+
# @returns [String] the pid component of the URI
|
155
|
+
def pid_from_uri(uri)
|
156
|
+
uri.gsub("info:fedora/", "")
|
209
157
|
end
|
210
|
-
|
158
|
+
|
211
159
|
end
|
212
160
|
end
|
213
161
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActiveFedora #:nodoc:
|
2
|
+
# = Active Fedora Serialization
|
3
|
+
module Serialization
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include ActiveModel::Serializers::JSON
|
6
|
+
|
7
|
+
included do
|
8
|
+
self.include_root_in_json = false
|
9
|
+
end
|
10
|
+
|
11
|
+
def serializable_hash(options = nil)
|
12
|
+
options = options.try(:clone) || {}
|
13
|
+
|
14
|
+
options[:except] = Array(options[:except]).map { |n| n.to_s }
|
15
|
+
|
16
|
+
super(options)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module ActiveFedora
|
2
|
+
module Sharding
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
class_attribute :fedora_connection
|
7
|
+
self.fedora_connection = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
# Uses {shard_index} to find or create the rubydora connection for this pid
|
12
|
+
# @param [String] pid the identifier of the object to get the connection for
|
13
|
+
# @return [Rubydora::Repository] The repository that the identifier exists in.
|
14
|
+
def connection_for_pid(pid)
|
15
|
+
idx = shard_index(pid)
|
16
|
+
unless fedora_connection.has_key? idx
|
17
|
+
if ActiveFedora.config.sharded?
|
18
|
+
fedora_connection[idx] = RubydoraConnection.new(ActiveFedora.config.credentials[idx])
|
19
|
+
else
|
20
|
+
fedora_connection[idx] = RubydoraConnection.new(ActiveFedora.config.credentials)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
fedora_connection[idx].connection
|
24
|
+
end
|
25
|
+
|
26
|
+
# This is where your sharding strategy is implemented -- it's how we figure out which shard an object will be (or was) written to.
|
27
|
+
# Given a pid, it decides which shard that pid will be written to (and thus retrieved from).
|
28
|
+
# For a given pid, as long as your shard configuration remains the same it will always return the same value.
|
29
|
+
# If you're not using sharding, this will always return 0, meaning use the first/only Fedora Repository in your configuration.
|
30
|
+
# Default strategy runs a modulo of the md5 of the pid against the number of shards.
|
31
|
+
# If you want to use a different sharding strategy, override this method. Make sure that it will always return the same value for a given pid and shard configuration.
|
32
|
+
#@return [Integer] the index of the shard this object is stored in
|
33
|
+
def shard_index(pid)
|
34
|
+
if ActiveFedora.config.sharded?
|
35
|
+
Digest::MD5.hexdigest(pid).hex % ActiveFedora.config.credentials.length
|
36
|
+
else
|
37
|
+
0
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
### if you are doing sharding, override this method to do something other than use a sequence
|
42
|
+
# @return [String] the unique pid for a new object
|
43
|
+
def assign_pid(obj)
|
44
|
+
args = {}
|
45
|
+
args[:namespace] = obj.namespace if obj.namespace
|
46
|
+
# TODO: This juggling of Fedora credentials & establishing connections should be handled by
|
47
|
+
# an establish_fedora_connection method,possibly wrap it all into a fedora_connection method - MZ 06-05-2012
|
48
|
+
if ActiveFedora.config.sharded?
|
49
|
+
credentials = ActiveFedora.config.credentials[0]
|
50
|
+
else
|
51
|
+
credentials = ActiveFedora.config.credentials
|
52
|
+
end
|
53
|
+
fedora_connection[0] ||= ActiveFedora::RubydoraConnection.new(credentials)
|
54
|
+
fedora_connection[0].connection.mint(args)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -1,11 +1,8 @@
|
|
1
1
|
module ActiveFedora
|
2
2
|
class SolrDigitalObject
|
3
|
-
|
4
3
|
include DigitalObject::DatastreamBootstrap
|
5
|
-
|
6
4
|
attr_reader :pid, :label, :state, :ownerId, :profile, :datastreams, :solr_doc
|
7
5
|
attr_accessor :original_class
|
8
|
-
|
9
6
|
def initialize(solr_doc, profile_hash, klass=ActiveFedora::Base)
|
10
7
|
@solr_doc = solr_doc
|
11
8
|
@pid = solr_doc[SOLR_DOCUMENT_ID]
|
@@ -17,7 +14,7 @@ module ActiveFedora
|
|
17
14
|
@datastreams = {}
|
18
15
|
|
19
16
|
dsids = profile_hash['datastreams'].keys
|
20
|
-
original_class = klass
|
17
|
+
self.original_class = klass
|
21
18
|
missing = dsids - klass.ds_specs.keys
|
22
19
|
missing.each do |dsid|
|
23
20
|
#Initialize the datastreams that are in the solr document, but not found in the classes spec.
|
@@ -43,11 +40,24 @@ module ActiveFedora
|
|
43
40
|
end
|
44
41
|
self
|
45
42
|
end
|
43
|
+
|
44
|
+
def fetch(field)
|
45
|
+
attribute = original_class.defined_attributes[field]
|
46
|
+
field_name = attribute.primary_solr_name
|
47
|
+
if field_name
|
48
|
+
val = solr_doc.fetch field_name
|
49
|
+
case attribute.type
|
50
|
+
when :date
|
51
|
+
val.is_a?(Array) ? val.map{|v| Date.parse v} : Date.parse(val)
|
52
|
+
else
|
53
|
+
val
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
46
57
|
|
47
58
|
def new?
|
48
59
|
false
|
49
60
|
end
|
50
|
-
alias_method :new_record?, :new?
|
51
61
|
|
52
62
|
def uri
|
53
63
|
"solr:#{pid}"
|