active-fedora 8.7.0 → 9.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (242) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +8 -15
  3. data/Gemfile +5 -5
  4. data/History.txt +0 -80
  5. data/README.md +1 -0
  6. data/Rakefile +0 -3
  7. data/active-fedora.gemspec +8 -7
  8. data/config/fedora.yml +5 -4
  9. data/config/predicate_mappings.yml +5 -5
  10. data/gemfiles/rails4.1.gemfile +10 -0
  11. data/gemfiles/rails4.2.beta.gemfile +10 -0
  12. data/lib/active_fedora.rb +151 -117
  13. data/lib/active_fedora/associations.rb +47 -15
  14. data/lib/active_fedora/associations/association.rb +29 -8
  15. data/lib/active_fedora/associations/association_scope.rb +5 -5
  16. data/lib/active_fedora/associations/belongs_to_association.rb +20 -63
  17. data/lib/active_fedora/associations/builder/association.rb +61 -25
  18. data/lib/active_fedora/associations/builder/belongs_to.rb +7 -94
  19. data/lib/active_fedora/associations/builder/collection_association.rb +11 -43
  20. data/lib/active_fedora/associations/builder/contains.rb +28 -0
  21. data/lib/active_fedora/associations/builder/has_and_belongs_to_many.rb +13 -3
  22. data/lib/active_fedora/associations/builder/has_many.rb +16 -10
  23. data/lib/active_fedora/associations/builder/property.rb +14 -0
  24. data/lib/active_fedora/associations/builder/singular_association.rb +14 -18
  25. data/lib/active_fedora/associations/builder/singular_property.rb +12 -0
  26. data/lib/active_fedora/associations/collection_association.rb +57 -80
  27. data/lib/active_fedora/associations/contains_association.rb +50 -0
  28. data/lib/active_fedora/associations/has_and_belongs_to_many_association.rb +44 -24
  29. data/lib/active_fedora/associations/has_many_association.rb +46 -14
  30. data/lib/active_fedora/associations/rdf.rb +86 -0
  31. data/lib/active_fedora/associations/singular_association.rb +4 -8
  32. data/lib/active_fedora/associations/singular_rdf.rb +15 -0
  33. data/lib/active_fedora/attached_files.rb +195 -0
  34. data/lib/active_fedora/attribute_methods.rb +122 -0
  35. data/lib/active_fedora/attribute_methods/dirty.rb +16 -0
  36. data/lib/active_fedora/attribute_methods/read.rb +61 -0
  37. data/lib/active_fedora/attribute_methods/write.rb +47 -0
  38. data/lib/active_fedora/attributes.rb +93 -44
  39. data/lib/active_fedora/attributes/primary_key.rb +12 -0
  40. data/lib/active_fedora/autosave_association.rb +2 -2
  41. data/lib/active_fedora/base.rb +16 -15
  42. data/lib/active_fedora/callbacks.rb +7 -7
  43. data/lib/active_fedora/change_set.rb +34 -0
  44. data/lib/active_fedora/cleaner.rb +62 -0
  45. data/lib/active_fedora/config.rb +4 -22
  46. data/lib/active_fedora/core.rb +173 -99
  47. data/lib/active_fedora/datastream.rb +4 -117
  48. data/lib/active_fedora/datastreams.rb +2 -263
  49. data/lib/active_fedora/datastreams/nokogiri_datastreams.rb +28 -51
  50. data/lib/active_fedora/{datastream_attribute.rb → delegated_attribute.rb} +57 -26
  51. data/lib/active_fedora/errors.rb +61 -0
  52. data/lib/active_fedora/fedora.rb +19 -0
  53. data/lib/active_fedora/fedora_attributes.rb +58 -26
  54. data/lib/active_fedora/file.rb +318 -0
  55. data/lib/active_fedora/file_configurator.rb +32 -32
  56. data/lib/active_fedora/file_path_builder.rb +24 -0
  57. data/lib/active_fedora/files_hash.rb +82 -0
  58. data/lib/active_fedora/fixity_service.rb +40 -0
  59. data/lib/active_fedora/indexing.rb +55 -82
  60. data/lib/active_fedora/indexing_service.rb +70 -0
  61. data/lib/active_fedora/ldp_resource.rb +26 -0
  62. data/lib/active_fedora/loadable_from_json.rb +112 -0
  63. data/lib/active_fedora/model.rb +5 -19
  64. data/lib/active_fedora/nested_attributes.rb +5 -6
  65. data/lib/active_fedora/nom_datastream.rb +15 -25
  66. data/lib/active_fedora/om_datastream.rb +26 -197
  67. data/lib/active_fedora/persistence.rb +95 -71
  68. data/lib/active_fedora/predicates.rb +4 -4
  69. data/lib/active_fedora/qualified_dublin_core_datastream.rb +17 -18
  70. data/lib/active_fedora/querying.rb +3 -4
  71. data/lib/active_fedora/railtie.rb +3 -6
  72. data/lib/active_fedora/rdf.rb +3 -1
  73. data/lib/active_fedora/rdf/datastream_indexing.rb +11 -0
  74. data/lib/active_fedora/rdf/fcrepo.rb +10 -324
  75. data/lib/active_fedora/rdf/indexing.rb +20 -16
  76. data/lib/active_fedora/rdf/ldp.rb +6 -0
  77. data/lib/active_fedora/rdf/ntriples_rdf_datastream.rb +1 -1
  78. data/lib/active_fedora/rdf/persistence.rb +5 -6
  79. data/lib/active_fedora/rdf/rdf_datastream.rb +44 -37
  80. data/lib/active_fedora/rdf/rdfxml_datastream.rb +13 -0
  81. data/lib/active_fedora/rdf/rels_ext.rb +26 -0
  82. data/lib/active_fedora/reflection.rb +256 -199
  83. data/lib/active_fedora/relation.rb +18 -6
  84. data/lib/active_fedora/relation/finder_methods.rb +69 -38
  85. data/lib/active_fedora/relation/query_methods.rb +7 -3
  86. data/lib/active_fedora/rspec_matchers/belong_to_associated_active_fedora_object_matcher.rb +7 -7
  87. data/lib/active_fedora/rspec_matchers/have_many_associated_active_fedora_objects_matcher.rb +8 -8
  88. data/lib/active_fedora/rspec_matchers/have_predicate_matcher.rb +9 -11
  89. data/lib/active_fedora/simple_datastream.rb +18 -13
  90. data/lib/active_fedora/solr_instance_loader.rb +18 -38
  91. data/lib/active_fedora/solr_service.rb +37 -20
  92. data/lib/active_fedora/sparql_insert.rb +45 -0
  93. data/lib/active_fedora/test_support.rb +1 -22
  94. data/lib/active_fedora/version.rb +1 -1
  95. data/lib/active_fedora/versionable.rb +90 -0
  96. data/lib/active_fedora/with_metadata.rb +37 -0
  97. data/lib/active_fedora/with_metadata/metadata_node.rb +70 -0
  98. data/lib/generators/active_fedora/config/config_generator.rb +0 -1
  99. data/lib/generators/active_fedora/config/solr/solr_generator.rb +1 -1
  100. data/lib/generators/active_fedora/model/model_generator.rb +5 -5
  101. data/lib/generators/active_fedora/model/templates/datastream_spec.rb.erb +1 -1
  102. data/lib/generators/active_fedora/model/templates/model_spec.rb.erb +2 -2
  103. data/lib/tasks/active_fedora_dev.rake +21 -27
  104. data/spec/config_helper.rb +1 -1
  105. data/spec/fixtures/mixed_rdf_descMetadata.nt +6 -6
  106. data/spec/fixtures/rails_root/config/predicate_mappings.yml +3 -19
  107. data/spec/fixtures/solr_rdf_descMetadata.nt +6 -6
  108. data/spec/integration/associations_spec.rb +133 -153
  109. data/spec/integration/attached_files_spec.rb +164 -0
  110. data/spec/integration/attributes_spec.rb +73 -12
  111. data/spec/integration/autosave_association_spec.rb +3 -3
  112. data/spec/integration/base_spec.rb +57 -351
  113. data/spec/integration/belongs_to_association_spec.rb +86 -76
  114. data/spec/integration/bug_spec.rb +3 -3
  115. data/spec/integration/collection_association_spec.rb +4 -4
  116. data/spec/integration/complex_rdf_datastream_spec.rb +54 -56
  117. data/spec/integration/delete_all_spec.rb +18 -15
  118. data/spec/integration/eradicate_spec.rb +54 -0
  119. data/spec/integration/fedora_solr_sync_spec.rb +7 -5
  120. data/spec/integration/field_to_solr_name_spec.rb +5 -5
  121. data/spec/integration/file_fixity_spec.rb +40 -0
  122. data/spec/integration/file_spec.rb +122 -0
  123. data/spec/integration/full_featured_model_spec.rb +53 -63
  124. data/spec/integration/has_and_belongs_to_many_associations_spec.rb +141 -114
  125. data/spec/integration/has_many_associations_spec.rb +142 -64
  126. data/spec/integration/json_serialization_spec.rb +50 -8
  127. data/spec/integration/model_spec.rb +12 -29
  128. data/spec/integration/nested_attribute_spec.rb +28 -20
  129. data/spec/integration/ntriples_datastream_spec.rb +60 -57
  130. data/spec/integration/om_datastream_spec.rb +51 -140
  131. data/spec/integration/rdf_nested_attributes_spec.rb +16 -14
  132. data/spec/integration/relation_delegation_spec.rb +7 -9
  133. data/spec/integration/relation_spec.rb +9 -7
  134. data/spec/integration/scoped_query_spec.rb +26 -26
  135. data/spec/integration/solr_instance_loader_spec.rb +69 -53
  136. data/spec/integration/solr_service_spec.rb +12 -73
  137. data/spec/integration/versionable_spec.rb +477 -0
  138. data/spec/integration/with_metadata_spec.rb +52 -0
  139. data/spec/samples/hydra-mods_article_datastream.rb +10 -6
  140. data/spec/samples/models/mods_article.rb +6 -2
  141. data/spec/samples/oral_history_sample.xml +1 -1
  142. data/spec/samples/oral_history_xml.xml +1 -1
  143. data/spec/samples/special_thing.rb +3 -3
  144. data/spec/spec_helper.rb +22 -12
  145. data/spec/support/an_active_model.rb +3 -7
  146. data/spec/unit/active_fedora_spec.rb +20 -17
  147. data/spec/unit/attached_files_spec.rb +203 -0
  148. data/spec/unit/attributes_spec.rb +286 -207
  149. data/spec/unit/base_active_model_spec.rb +8 -8
  150. data/spec/unit/base_datastream_management_spec.rb +11 -24
  151. data/spec/unit/base_extra_spec.rb +17 -67
  152. data/spec/unit/base_spec.rb +163 -428
  153. data/spec/unit/builder/has_and_belongs_to_many_spec.rb +2 -2
  154. data/spec/unit/callback_spec.rb +38 -23
  155. data/spec/unit/change_set_spec.rb +46 -0
  156. data/spec/unit/code_configurator_spec.rb +5 -5
  157. data/spec/unit/config_spec.rb +9 -14
  158. data/spec/unit/core_spec.rb +59 -8
  159. data/spec/unit/file_configurator_spec.rb +55 -53
  160. data/spec/unit/file_path_builder_spec.rb +18 -0
  161. data/spec/unit/file_spec.rb +221 -0
  162. data/spec/unit/files_hash_spec.rb +53 -0
  163. data/spec/unit/fixity_service_spec.rb +34 -0
  164. data/spec/unit/has_and_belongs_to_many_association_spec.rb +134 -0
  165. data/spec/unit/has_many_association_spec.rb +51 -0
  166. data/spec/unit/indexing_service_spec.rb +23 -0
  167. data/spec/unit/indexing_spec.rb +26 -0
  168. data/spec/unit/inheritance_spec.rb +9 -10
  169. data/spec/unit/model_spec.rb +15 -33
  170. data/spec/unit/nom_datastream_spec.rb +13 -10
  171. data/spec/unit/ntriples_datastream_spec.rb +81 -96
  172. data/spec/unit/om_datastream_spec.rb +137 -227
  173. data/spec/unit/persistence_spec.rb +28 -34
  174. data/spec/unit/predicates_spec.rb +29 -29
  175. data/spec/unit/property_spec.rb +1 -3
  176. data/spec/unit/qualified_dublin_core_datastream_spec.rb +27 -32
  177. data/spec/unit/query_spec.rb +116 -149
  178. data/spec/unit/rdf_datastream_spec.rb +25 -43
  179. data/spec/unit/rdf_resource_datastream_spec.rb +24 -123
  180. data/spec/unit/{rdfxml_rdf_datastream_spec.rb → rdfxml_datastream_spec.rb} +21 -25
  181. data/spec/unit/readonly_spec.rb +23 -0
  182. data/spec/unit/rspec_matchers/belong_to_associated_active_fedora_object_matcher_spec.rb +6 -6
  183. data/spec/unit/rspec_matchers/have_many_associated_active_fedora_objects_matcher_spec.rb +6 -6
  184. data/spec/unit/rspec_matchers/have_predicate_matcher_spec.rb +6 -6
  185. data/spec/unit/serializers_spec.rb +1 -1
  186. data/spec/unit/simple_datastream_spec.rb +12 -23
  187. data/spec/unit/solr_config_options_spec.rb +14 -17
  188. data/spec/unit/solr_service_spec.rb +38 -77
  189. data/spec/unit/sparql_insert_spec.rb +32 -0
  190. data/spec/unit/validations_spec.rb +8 -11
  191. metadata +96 -121
  192. data/lib/active_fedora/auditable.rb +0 -9
  193. data/lib/active_fedora/content_model.rb +0 -70
  194. data/lib/active_fedora/datastream_collections.rb +0 -302
  195. data/lib/active_fedora/datastream_hash.rb +0 -35
  196. data/lib/active_fedora/digital_object.rb +0 -55
  197. data/lib/active_fedora/fixture_exporter.rb +0 -33
  198. data/lib/active_fedora/fixture_loader.rb +0 -48
  199. data/lib/active_fedora/rdf/identifiable.rb +0 -66
  200. data/lib/active_fedora/rdf/project_hydra.rb +0 -12
  201. data/lib/active_fedora/rdf/rdfxml_rdf_datastream.rb +0 -13
  202. data/lib/active_fedora/rdf_xml_writer.rb +0 -49
  203. data/lib/active_fedora/relationship_graph.rb +0 -101
  204. data/lib/active_fedora/reload_on_save.rb +0 -16
  205. data/lib/active_fedora/rels_ext_datastream.rb +0 -100
  206. data/lib/active_fedora/rspec_matchers/match_fedora_datastream_matcher.rb +0 -41
  207. data/lib/active_fedora/rubydora_connection.rb +0 -35
  208. data/lib/active_fedora/semantic_node.rb +0 -164
  209. data/lib/active_fedora/service_definitions.rb +0 -88
  210. data/lib/active_fedora/sharding.rb +0 -58
  211. data/lib/active_fedora/solr_digital_object.rb +0 -68
  212. data/lib/active_fedora/unsaved_digital_object.rb +0 -58
  213. data/lib/generators/active_fedora/config/fedora/fedora_generator.rb +0 -12
  214. data/lib/generators/active_fedora/config/fedora/templates/fedora.yml +0 -38
  215. data/lib/generators/active_fedora/config/fedora/templates/fedora_conf/conf/development/fedora.fcfg +0 -953
  216. data/lib/generators/active_fedora/config/fedora/templates/fedora_conf/conf/test/fedora.fcfg +0 -953
  217. data/lib/tasks/active_fedora.rake +0 -83
  218. data/spec/fixtures/sharded_fedora.yml +0 -11
  219. data/spec/integration/auditable_spec.rb +0 -29
  220. data/spec/integration/datastream_collections_spec.rb +0 -127
  221. data/spec/integration/datastream_spec.rb +0 -90
  222. data/spec/integration/datastreams_spec.rb +0 -173
  223. data/spec/integration/load_from_solr_spec.rb +0 -66
  224. data/spec/integration/rels_ext_datastream_spec.rb +0 -82
  225. data/spec/support/mock_fedora.rb +0 -44
  226. data/spec/unit/content_model_spec.rb +0 -86
  227. data/spec/unit/datastream_collections_spec.rb +0 -420
  228. data/spec/unit/datastream_spec.rb +0 -83
  229. data/spec/unit/datastreams_spec.rb +0 -243
  230. data/spec/unit/has_and_belongs_to_many_collection_spec.rb +0 -96
  231. data/spec/unit/has_many_collection_spec.rb +0 -35
  232. data/spec/unit/rdf_vocab_spec.rb +0 -30
  233. data/spec/unit/rdf_xml_writer_spec.rb +0 -63
  234. data/spec/unit/relationship_graph_spec.rb +0 -115
  235. data/spec/unit/reload_on_save_spec.rb +0 -24
  236. data/spec/unit/rels_ext_datastream_spec.rb +0 -170
  237. data/spec/unit/rspec_matchers/match_fedora_datastream_matcher_spec.rb +0 -44
  238. data/spec/unit/rubydora_connection_spec.rb +0 -12
  239. data/spec/unit/semantic_node_spec.rb +0 -112
  240. data/spec/unit/service_definitions_spec.rb +0 -63
  241. data/spec/unit/solr_digital_object_spec.rb +0 -97
  242. data/spec/unit/unsaved_digital_object_spec.rb +0 -48
@@ -0,0 +1,12 @@
1
+ module ActiveFedora
2
+ module Attributes
3
+ module PrimaryKey
4
+
5
+ # If the id is "/foo:1" then to_key ought to return ["foo:1"]
6
+ def to_key
7
+ id && [id]
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -154,7 +154,7 @@ module ActiveFedora
154
154
  end
155
155
 
156
156
  # Reloads the attributes of the object as usual and clears <tt>marked_for_destruction</tt> flag.
157
- def reload(options = nil)
157
+ def reload
158
158
  @marked_for_destruction = false
159
159
  super
160
160
  end
@@ -305,7 +305,7 @@ module ActiveFedora
305
305
  saved = record.save(:validate => !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
306
306
 
307
307
  if association.updated?
308
- self[reflection.name.to_s + "_id"] = record.id
308
+ self[reflection.name.to_s + "_id"] = record.id #TODO use primary_key here
309
309
  association.loaded!
310
310
  end
311
311
 
@@ -1,10 +1,10 @@
1
1
  SOLR_DOCUMENT_ID = "id" unless (defined?(SOLR_DOCUMENT_ID) && !SOLR_DOCUMENT_ID.nil?)
2
2
  ENABLE_SOLR_UPDATES = true unless defined?(ENABLE_SOLR_UPDATES)
3
- require "digest"
4
3
  require 'active_support/descendants_tracker'
4
+ require 'active_fedora/errors'
5
5
 
6
6
  module ActiveFedora
7
-
7
+
8
8
  # This class ties together many of the lower-level modules, and
9
9
  # implements something akin to an ActiveRecord-alike interface to
10
10
  # fedora. If you want to represent a fedora object in the ruby
@@ -14,38 +14,39 @@ module ActiveFedora
14
14
  # class Oralhistory < ActiveFedora::Base
15
15
  # has_metadata "properties", type: ActiveFedora::SimpleDatastream do |m|
16
16
  # m.field "narrator", :string
17
- # m.field "bio", :text
17
+ # m.field "narrator", :text
18
18
  # end
19
19
  # end
20
20
  #
21
- # The above example creates a Fedora object with a metadata datastream named "properties", which is composed of a
21
+ # The above example creates a Fedora object with a metadata datastream named "properties", which is composed of a
22
22
  # narrator and bio field.
23
23
  #
24
- # Datastreams defined with +has_metadata+ are accessed via the +datastreams+ member hash.
24
+ # Attached files defined with +contains+ are accessed via the +attached_files+ member hash.
25
25
  #
26
26
  class Base
27
27
  extend ActiveModel::Naming
28
28
  extend ActiveSupport::DescendantsTracker
29
- include SemanticNode
30
- include Sharding
31
- include ActiveFedora::Persistence
32
- include Scoping
29
+
30
+ include Core
31
+ include Persistence
33
32
  include Indexing
33
+ include Scoping
34
34
  include ActiveModel::Conversion
35
- include Validations
36
35
  include Callbacks
37
- include Datastreams
36
+ include Validations
38
37
  extend Querying
39
38
  include Associations
40
39
  include AutosaveAssociation
41
40
  include NestedAttributes
42
41
  include Reflection
43
- include Attributes
44
42
  include Serialization
45
- include Core
43
+
44
+ include AttachedFiles
46
45
  include FedoraAttributes
47
- include ReloadOnSave
48
- include ActiveFedora::RDF::Identifiable
46
+ include AttributeMethods
47
+ include Attributes
48
+ include Versionable
49
+ include LoadableFromJson
49
50
  end
50
51
 
51
52
  ActiveSupport.run_load_hooks(:active_fedora, Base)
@@ -232,16 +232,16 @@ module ActiveFedora
232
232
 
233
233
  private
234
234
 
235
- def persist(should_update_index) #:nodoc:
236
- run_callbacks(:save) { super }
237
- end
238
-
239
- def create(*) #:nodoc:
240
- run_callbacks(:create) { super }
235
+ def create_record(*) #:nodoc:
236
+ run_callbacks(:create) {
237
+ run_callbacks(:save) { super }
238
+ }
241
239
  end
242
240
 
243
241
  def update_record(*) #:nodoc:
244
- run_callbacks(:update) { super }
242
+ run_callbacks(:update) {
243
+ run_callbacks(:save) { super }
244
+ }
245
245
  end
246
246
  end
247
247
  end
@@ -0,0 +1,34 @@
1
+ module ActiveFedora
2
+ # a Hash of properties that have changed and their present values
3
+ class ChangeSet
4
+
5
+ attr_reader :object, :graph, :changed_attributes
6
+
7
+ # @param [ActiveFedora::Base] object The resource that has associations and properties
8
+ # @param [RDF::Graph] graph The RDF graph that holds the current state
9
+ # @param [Array] changed_attributes A list of properties that have changed
10
+ def initialize(object, graph, changed_attributes)
11
+ @object = object
12
+ @graph = graph
13
+ @changed_attributes = changed_attributes
14
+ end
15
+
16
+ def empty?
17
+ changes.empty?
18
+ end
19
+
20
+ def changes
21
+ @changes ||= changed_attributes.each_with_object({}) do |key, result|
22
+ if m = /^.*_ids?$/.match(key)
23
+ predicate = object.association(m[0].to_sym).reflection.predicate
24
+ result[predicate] = graph.query(predicate: predicate)
25
+ elsif object.class.properties.keys.include?(key)
26
+ predicate = graph.reflections.reflect_on_property(key).predicate
27
+ result[predicate] = graph.query(predicate: predicate)
28
+ elsif object.local_attributes.include?(key)
29
+ raise "Unable to find a graph predicate corresponding to the attribute: \"#{key}\""
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,62 @@
1
+ module ActiveFedora
2
+ module Cleaner
3
+ def self.clean!
4
+ cleanout_fedora
5
+ reinitialize_repo
6
+ cleanout_solr
7
+ end
8
+
9
+ def self.cleanout_fedora
10
+ begin
11
+ delete_root_resource
12
+ delete_tombstone
13
+ rescue Ldp::HttpError => exception
14
+ log "#cleanout_fedora in spec_helper.rb raised #{exception}"
15
+ end
16
+ end
17
+
18
+ def self.delete_root_resource
19
+ begin
20
+ connection.delete(root_resource_path)
21
+ rescue Ldp::Gone
22
+ end
23
+ end
24
+
25
+ def self.delete_tombstone
26
+ connection.delete(tombstone_path)
27
+ end
28
+
29
+ def self.tombstone_path
30
+ root_resource_path + "/fcr:tombstone"
31
+ end
32
+
33
+ def self.root_resource_path
34
+ ActiveFedora.fedora.base_path.sub('/', '')
35
+ end
36
+
37
+ def self.connection
38
+ ActiveFedora.fedora.connection
39
+ end
40
+
41
+ def self.solr_connection
42
+ ActiveFedora::SolrService.instance && ActiveFedora::SolrService.instance.conn
43
+ end
44
+
45
+ def self.cleanout_solr
46
+ restore_spec_configuration if solr_connection.nil?
47
+ solr_connection.delete_by_query('*:*', params: {'softCommit' => true})
48
+ end
49
+
50
+ def self.reinitialize_repo
51
+ begin
52
+ ActiveFedora.fedora.connection.put(root_resource_path, "")
53
+ rescue Ldp::HttpError => exception
54
+ log "#reinitialize_repo in spec_helper.rb raised #{exception}"
55
+ end
56
+ end
57
+
58
+ def self.log(message)
59
+ ActiveFedora::Base.logger.debug message if ActiveFedora::Base.logger
60
+ end
61
+ end
62
+ end
@@ -1,29 +1,11 @@
1
- module ActiveFedora
1
+ module ActiveFedora
2
2
  class Config
3
3
  attr_reader :credentials
4
4
  def initialize(val)
5
- if val.is_a? Array
6
- init_shards(val)
7
- else
8
- init_single(val)
5
+ @credentials = val.symbolize_keys
6
+ unless @credentials.has_key?(:url)
7
+ raise ActiveFedora::ConfigurationError, "Fedora configuration must provide :url."
9
8
  end
10
9
  end
11
-
12
- def sharded?
13
- credentials.is_a? Array
14
- end
15
-
16
- private
17
-
18
- def init_shards(vals)
19
- @credentials = vals.map(&:symbolize_keys)
20
- end
21
-
22
- def init_single(vals)
23
- @credentials = vals.symbolize_keys
24
- unless @credentials.has_key?(:user) && @credentials.has_key?(:password) && @credentials.has_key?(:url)
25
- raise ActiveFedora::ConfigurationError, "Fedora configuration must provide :user, :password and :url."
26
- end
27
- end
28
10
  end
29
11
  end
@@ -1,8 +1,7 @@
1
1
  module ActiveFedora
2
2
  module Core
3
3
  extend ActiveSupport::Concern
4
-
5
- attr_reader :inner_object
4
+
6
5
  included do
7
6
  ##
8
7
  # :singleton-method:
@@ -10,58 +9,66 @@ module ActiveFedora
10
9
  # Accepts a logger conforming to the interface of Log4r which can be
11
10
  # retrieved on both a class and instance level by calling +logger+.
12
11
  mattr_accessor :logger, instance_writer: false
12
+
13
+ ##
14
+ # :singleton-method
15
+ #
16
+ # Accepts a proc that takes an id and transforms it to a URI
17
+ mattr_accessor :translate_id_to_uri, instance_writer: false
18
+
19
+ ##
20
+ # :singleton-method
21
+ #
22
+ # Accepts a proc that takes a uri and transforms it to an id
23
+ mattr_accessor :translate_uri_to_id, instance_writer: false
24
+
13
25
  end
14
26
 
15
- # Constructor. You may supply a custom +:pid+, or we call the Fedora Rest API for the
16
- # next available Fedora pid, and mark as new object.
17
- # Also, if +attrs+ does not contain +:pid+ but does contain +:namespace+ it will pass the
18
- # +:namespace+ value to Fedora::Repository.nextid to generate the next pid available within
27
+ def ldp_source
28
+ @ldp_source
29
+ end
30
+
31
+ # Constructor. You may supply a custom +:id+, or we call the Fedora Rest API for the
32
+ # next available Fedora id, and mark as new object.
33
+ # Also, if +attrs+ does not contain +:id+ but does contain +:namespace+ it will pass the
34
+ # +:namespace+ value to Fedora::Repository.nextid to generate the next id available within
19
35
  # the given namespace.
20
- def initialize(attrs = nil)
21
- attrs = {} if attrs.nil?
22
- @association_cache = {}
23
- attributes = attrs.dup
24
- @inner_object = UnsavedDigitalObject.new(self.class, attributes.delete(:namespace), attributes.delete(:pid))
25
- self.relationships_loaded = true
26
- load_datastreams
27
-
28
- [:new_object,:create_date, :modified_date].each { |k| attributes.delete(k)}
29
- self.attributes=attributes
36
+ def initialize(attributes_or_resource_or_url = nil, &block)
37
+ init_internals
38
+ attributes = initialize_resource_and_attributes(attributes_or_resource_or_url)
39
+ raise IllegalOperation, "Attempting to recreate existing ldp_source" unless ldp_source.new?
40
+ assert_content_model
41
+ load_attached_files
42
+ self.attributes = attributes if attributes
43
+
44
+ yield self if block_given?
30
45
  run_callbacks :initialize
31
46
  end
32
47
 
33
48
  # Reloads the object from Fedora.
34
49
  def reload
35
- raise ActiveFedora::ObjectNotFoundError, "Can't reload an object that hasn't been saved" unless persisted?
50
+ check_persistence unless persisted?
36
51
  clear_association_cache
37
- clear_relationships
38
- init_with_object(self.class.find(self.pid).inner_object)
52
+ clear_attached_files
53
+ @ldp_source = LdpResource.new(conn, uri)
54
+ @resource = nil
55
+ load_attached_files
56
+ self
39
57
  end
40
58
 
41
- # Initialize an empty model object and set the +inner_obj+
59
+ # Initialize an empty model object and set its +resource+
42
60
  # example:
43
61
  #
44
62
  # class Post < ActiveFedora::Base
45
- # has_metadata :name => "properties", :type => ActiveFedora::SimpleDatastream
46
63
  # end
47
64
  #
48
65
  # post = Post.allocate
49
- # post.init_with_object(DigitalObject.find(pid))
50
- # post.properties.title # => 'hello world'
51
- def init_with_object(inner_obj)
52
- @association_cache = {}
53
- @inner_object = inner_obj
54
- unless @inner_object.is_a? SolrDigitalObject
55
- @inner_object.original_class = self.class
56
- ## Replace existing unchanged datastreams with the definitions found in this class if they have a different type.
57
- ## Any datastream that is deleted here will cause a reload from fedora, so avoid it whenever possible
58
- ds_specs.keys.each do |key|
59
- if @inner_object.datastreams[key] != nil && !@inner_object.datastreams[key].content_changed? && @inner_object.datastreams[key].class != self.class.ds_specs[key][:type]
60
- @inner_object.datastreams.delete(key)
61
- end
62
- end
63
- end
64
- load_datastreams
66
+ # post.init_with_resource(Ldp::Resource.new('http://example.com/post/1'))
67
+ # post.title # => 'hello world'
68
+ def init_with_resource(rdf_resource)
69
+ init_internals
70
+ @ldp_source = rdf_resource
71
+ load_attached_files
65
72
  run_callbacks :find
66
73
  run_callbacks :initialize
67
74
  self
@@ -70,93 +77,160 @@ module ActiveFedora
70
77
  def ==(comparison_object)
71
78
  comparison_object.equal?(self) ||
72
79
  (comparison_object.instance_of?(self.class) &&
73
- comparison_object.pid == pid &&
80
+ comparison_object.id == id &&
74
81
  !comparison_object.new_record?)
75
82
  end
76
83
 
77
- def clone
78
- new_object = self.class.create
79
- clone_into(new_object)
84
+ def freeze
85
+ @resource.freeze
86
+ #@attributes = @attributes.clone.freeze
87
+ attached_files.freeze
88
+ self
80
89
  end
81
90
 
82
- # Clone the datastreams from this object into the provided object, while preserving the pid of the provided object
83
- # @param [Base] new_object clone into this object
84
- def clone_into(new_object)
85
- rels = Nokogiri::XML( rels_ext.content)
86
- rels.xpath("//rdf:Description/@rdf:about").first.value = new_object.internal_uri
87
- new_object.rels_ext.content = rels.to_xml
91
+ def frozen?
92
+ attached_files.frozen?
93
+ end
88
94
 
89
- datastreams.each do |k, v|
90
- next if k == 'RELS-EXT'
91
- new_object.datastreams[k].content = v.content
92
- end
93
- new_object if new_object.save
95
+ # Returns +true+ if the record is read only. Records loaded through joins with piggy-back
96
+ # attributes will be marked as read only since they cannot be saved.
97
+ def readonly?
98
+ @readonly
94
99
  end
95
100
 
96
- def freeze
97
- datastreams.freeze
98
- self
101
+ # Marks this record as read only.
102
+ def readonly!
103
+ @readonly = true
99
104
  end
100
105
 
101
- def frozen?
102
- datastreams.frozen?
106
+ def to_uri(id)
107
+ self.class.id_to_uri(id)
103
108
  end
104
109
 
105
- def pretty_pid
106
- if self.pid == UnsavedDigitalObject::PLACEHOLDER
107
- nil
108
- else
109
- self.pid
110
+ protected
111
+
112
+ # This can be overriden to assert a different model
113
+ # It's normally called once in the lifecycle, by #create#
114
+ def assert_content_model
115
+ self.has_model = self.class.to_s
110
116
  end
111
- end
112
117
 
113
- # This method adapts the inner_object to a new ActiveFedora::Base implementation
114
- # This is intended to minimize redundant interactions with Fedora
115
- def adapt_to(klass)
116
- unless klass.ancestors.include? ActiveFedora::Base
117
- raise "Cannot adapt #{self.class.name} to #{klass.name}: Not a ActiveFedora::Base subclass"
118
+ module ClassMethods
119
+ def generated_association_methods
120
+ @generated_association_methods ||= begin
121
+ mod = const_set(:GeneratedAssociationMethods, Module.new)
122
+ include mod
123
+ mod
124
+ end
118
125
  end
119
- klass.allocate.init_with_object(inner_object)
120
- end
121
126
 
122
- # Adapts the inner object to the best known model
123
- # Raise ActiveFedora::ModelNotAsserted if unable to adapt object
124
- # (i.e, best model is nil)
125
- def adapt_to_cmodel
126
- best_model_match = ActiveFedora::ContentModel.best_model_for(self)
127
+ # Returns a suitable uri object for :has_model
128
+ # Should reverse Model#from_class_uri
129
+ # TODO this is a poorly named method
130
+ def to_class_uri(attrs = {})
131
+ name
132
+ end
127
133
 
128
- if best_model_match.nil?
129
- raise ActiveFedora::ModelNotAsserted, "Unable to adapt #{self.inspect} to a model asserted for the resource."
134
+ ##
135
+ # Transforms an id into a uri
136
+ # if translate_id_to_uri is set it uses that proc, otherwise just the default
137
+ def id_to_uri(id)
138
+ if translate_id_to_uri
139
+ translate_id_to_uri.call(id)
140
+ else
141
+ id = "/#{id}" unless id.start_with? '/'
142
+ id = ActiveFedora.fedora.base_path + id unless id.start_with? "#{ActiveFedora.fedora.base_path}/"
143
+ ActiveFedora.fedora.host + id
144
+ end
130
145
  end
131
146
 
132
- self.instance_of?(best_model_match) ? self : self.adapt_to(best_model_match)
133
- end
134
-
135
- # ** EXPERIMENTAL **
136
- # This method returns a new object of the same class, with the internal SolrDigitalObject
137
- # replaced with an actual DigitalObject.
138
- def reify
139
- if self.inner_object.is_a? DigitalObject
140
- raise "#{self.inspect} is already a full digital object"
147
+ ##
148
+ # Transforms a uri into an id
149
+ # if translate_uri_to_id is set it uses that proc, otherwise just the default
150
+ def uri_to_id(uri)
151
+ if translate_uri_to_id
152
+ translate_uri_to_id.call(uri)
153
+ else
154
+ id = uri.to_s.sub(ActiveFedora.fedora.host + ActiveFedora.fedora.base_path, '')
155
+ id.start_with?('/') ? id[1..-1] : id
156
+ end
141
157
  end
142
- self.class.find self.pid
143
- end
144
-
145
- # ** EXPERIMENTAL **
146
- # This method reinitializes a lightweight, loaded-from-solr object with an actual
147
- # DigitalObject inside.
148
- def reify!
149
- if self.inner_object.is_a? DigitalObject
150
- raise "#{self.inspect} is already a full digital object"
158
+
159
+ ##
160
+ # Provides the common interface for ActiveTriples::Identifiable
161
+ def from_uri(uri,_)
162
+ begin
163
+ self.find(uri_to_id(uri))
164
+ rescue ActiveFedora::ObjectNotFoundError, Ldp::Gone
165
+ ActiveTriples::Resource.new(uri)
166
+ end
151
167
  end
152
- self.init_with_object DigitalObject.find(self.class,self.pid)
153
- end
154
-
155
- module ClassMethods
168
+
156
169
  private
170
+
157
171
  def relation
158
172
  Relation.new(self)
159
173
  end
160
174
  end
175
+
176
+ private
177
+
178
+ def init_internals
179
+ @resource = nil
180
+ @readonly = false
181
+ @association_cache = {}
182
+ end
183
+
184
+ def conn
185
+ ActiveFedora.fedora.connection
186
+ end
187
+
188
+ def build_ldp_resource(id=nil)
189
+ if id
190
+ LdpResource.new(conn, to_uri(id))
191
+ else
192
+ LdpResource.new(conn, nil, nil, ActiveFedora.fedora.host + ActiveFedora.fedora.base_path)
193
+ end
194
+ end
195
+
196
+ def check_persistence
197
+ if destroyed?
198
+ raise ActiveFedora::ObjectNotFoundError, "Can't reload an object that has been destroyed"
199
+ else
200
+ raise ActiveFedora::ObjectNotFoundError, "Can't reload an object that hasn't been saved"
201
+ end
202
+ end
203
+
204
+ def initialize_resource_and_attributes attributes_or_resource_or_url
205
+ case attributes_or_resource_or_url
206
+ when String
207
+ @ldp_source = build_ldp_resource(attributes_or_resource_or_url)
208
+ @attributes = {}.with_indifferent_access
209
+ when Hash
210
+ attributes = attributes_or_resource_or_url
211
+
212
+ id = attributes.delete(:id)
213
+
214
+ # TODO: Remove when we decide using 'pid' is no longer supported.
215
+ if !id && attributes.has_key?(:pid)
216
+ Deprecation.warn Core, 'Initializing with :pid is deprecated and will be removed in active-fedora 10.0. Use :id instead'
217
+ id = attributes.delete(:pid)
218
+ end
219
+
220
+ attributes = attributes.with_indifferent_access if attributes
221
+ @ldp_source = if id
222
+ build_ldp_resource(id)
223
+ else
224
+ build_ldp_resource
225
+ end
226
+ when NilClass
227
+ @ldp_source = build_ldp_resource
228
+ attributes = {}.with_indifferent_access
229
+ else
230
+ raise ArgumentError, "#{attributes_or_resource_or_url.class} is not acceptable"
231
+ end
232
+ return attributes
233
+ end
234
+
161
235
  end
162
236
  end