ddr-models 2.11.0 → 3.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (268) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.travis.yml +7 -6
  4. data/Gemfile +2 -3
  5. data/Rakefile +5 -5
  6. data/app/controllers/users/sessions_controller.rb +5 -0
  7. data/app/helpers/models_helper.rb +7 -0
  8. data/app/models/attachment.rb +3 -5
  9. data/app/models/collection.rb +12 -79
  10. data/app/models/component.rb +8 -67
  11. data/app/models/item.rb +8 -73
  12. data/app/models/target.rb +6 -5
  13. data/config/initializers/active_fedora_base.rb +11 -30
  14. data/config/initializers/{active_fedora_datastream.rb → active_fedora_file.rb} +1 -1
  15. data/config/initializers/devise.rb +2 -3
  16. data/config/initializers/subscriptions.rb +2 -19
  17. data/ddr-models.gemspec +10 -14
  18. data/lib/ddr/actions/fixity_check.rb +1 -1
  19. data/lib/ddr/actions/virus_check.rb +17 -10
  20. data/lib/ddr/auth.rb +6 -38
  21. data/lib/ddr/auth/ability.rb +1 -5
  22. data/lib/ddr/auth/ability_definitions/collection_ability_definitions.rb +0 -16
  23. data/lib/ddr/auth/ability_definitions/datastream_ability_definitions.rb +10 -4
  24. data/lib/ddr/auth/ability_definitions/role_based_ability_definitions.rb +16 -9
  25. data/lib/ddr/auth/ability_factory.rb +25 -2
  26. data/lib/ddr/auth/abstract_ability.rb +1 -2
  27. data/lib/ddr/auth/auth_context.rb +0 -18
  28. data/lib/ddr/auth/auth_context_factory.rb +2 -0
  29. data/lib/ddr/auth/group.rb +0 -6
  30. data/lib/ddr/auth/grouper_gateway.rb +0 -24
  31. data/lib/ddr/auth/permissions.rb +1 -12
  32. data/lib/ddr/auth/role_based_access_controls_enforcement.rb +5 -5
  33. data/lib/ddr/auth/roles.rb +1 -11
  34. data/lib/ddr/auth/roles/role_set.rb +0 -7
  35. data/lib/ddr/auth/roles/roles_datastream.rb +9 -0
  36. data/lib/ddr/contacts.rb +25 -0
  37. data/lib/ddr/datastreams.rb +10 -28
  38. data/lib/ddr/datastreams/datastream_behavior.rb +30 -100
  39. data/lib/ddr/datastreams/descriptive_metadata_datastream.rb +28 -31
  40. data/lib/ddr/datastreams/fits_datastream.rb +9 -22
  41. data/lib/ddr/datastreams/metadata_datastream.rb +17 -31
  42. data/lib/ddr/derivatives.rb +13 -16
  43. data/lib/ddr/derivatives/derivative.rb +68 -0
  44. data/lib/ddr/derivatives/{generator.rb → generators/generator.rb} +11 -7
  45. data/lib/ddr/derivatives/generators/png_generator.rb +23 -0
  46. data/lib/ddr/derivatives/generators/ptif_generator.rb +56 -0
  47. data/lib/ddr/derivatives/multires_image.rb +59 -0
  48. data/lib/ddr/derivatives/thumbnail.rb +36 -0
  49. data/lib/ddr/events.rb +0 -1
  50. data/lib/ddr/events/deletion_event.rb +9 -5
  51. data/lib/ddr/events/event.rb +8 -13
  52. data/lib/ddr/events/fixity_check_event.rb +0 -6
  53. data/lib/ddr/events/ingestion_event.rb +9 -5
  54. data/lib/ddr/events/update_event.rb +4 -17
  55. data/lib/ddr/index.rb +4 -4
  56. data/lib/ddr/index/abstract_query_result.rb +4 -3
  57. data/lib/ddr/index/connection.rb +9 -28
  58. data/lib/ddr/index/csv_query_result.rb +32 -47
  59. data/lib/ddr/index/field.rb +1 -11
  60. data/lib/ddr/index/fields.rb +16 -99
  61. data/lib/ddr/index/filter.rb +30 -103
  62. data/lib/ddr/index/filters.rb +19 -0
  63. data/lib/ddr/index/query.rb +11 -58
  64. data/lib/ddr/index/query_builder.rb +36 -147
  65. data/lib/ddr/index/query_clause.rb +19 -79
  66. data/lib/ddr/index/query_result.rb +4 -36
  67. data/lib/ddr/index/query_value.rb +18 -0
  68. data/lib/ddr/index/response.rb +2 -19
  69. data/lib/ddr/jobs.rb +12 -0
  70. data/lib/ddr/jobs/fits_file_characterization.rb +51 -0
  71. data/lib/ddr/jobs/permanent_id.rb +23 -0
  72. data/lib/ddr/managers.rb +1 -0
  73. data/lib/ddr/managers/derivatives_manager.rb +53 -93
  74. data/lib/ddr/managers/permanent_id_manager.rb +91 -0
  75. data/lib/ddr/managers/technical_metadata_manager.rb +10 -24
  76. data/lib/ddr/managers/workflow_manager.rb +10 -29
  77. data/lib/ddr/models.rb +50 -101
  78. data/lib/ddr/models/access_controllable.rb +12 -0
  79. data/lib/ddr/models/admin_set.rb +5 -16
  80. data/lib/ddr/models/base.rb +45 -165
  81. data/lib/ddr/models/describable.rb +19 -21
  82. data/lib/ddr/models/engine.rb +11 -39
  83. data/lib/ddr/models/error.rb +0 -3
  84. data/lib/ddr/models/file_management.rb +36 -72
  85. data/lib/ddr/models/finding_aid.rb +2 -35
  86. data/lib/ddr/models/fixity_checkable.rb +4 -0
  87. data/lib/ddr/models/governable.rb +3 -1
  88. data/lib/ddr/models/has_admin_metadata.rb +82 -56
  89. data/lib/ddr/models/has_attachments.rb +3 -1
  90. data/lib/ddr/models/has_children.rb +3 -7
  91. data/lib/ddr/models/has_content.rb +35 -32
  92. data/lib/ddr/models/has_multires_image.rb +7 -12
  93. data/lib/ddr/models/has_struct_metadata.rb +44 -6
  94. data/lib/ddr/models/has_thumbnail.rb +1 -4
  95. data/lib/ddr/models/indexing.rb +97 -186
  96. data/lib/ddr/models/licenses/admin_policy_license.rb +11 -0
  97. data/lib/ddr/models/licenses/effective_license.rb +9 -0
  98. data/lib/ddr/models/licenses/inherited_license.rb +9 -0
  99. data/lib/ddr/models/licenses/license.rb +21 -0
  100. data/lib/ddr/models/licenses/parent_license.rb +11 -0
  101. data/lib/ddr/models/metadata/descriptive_metadata.rb +50 -0
  102. data/lib/ddr/models/metadata/metadata.rb +37 -0
  103. data/lib/ddr/models/metadata/metadata_mapper.rb +32 -0
  104. data/lib/ddr/models/metadata/metadata_mappers.rb +18 -0
  105. data/lib/ddr/models/metadata/metadata_term.rb +24 -0
  106. data/lib/ddr/models/metadata/metadata_vocabularies.rb +18 -0
  107. data/lib/ddr/models/metadata/metadata_vocabulary.rb +34 -0
  108. data/lib/ddr/models/solr_document.rb +24 -156
  109. data/lib/ddr/models/struct_div.rb +63 -0
  110. data/lib/ddr/models/structure.rb +39 -175
  111. data/lib/ddr/models/version.rb +1 -1
  112. data/lib/ddr/models/year_facet.rb +118 -60
  113. data/lib/ddr/notifications.rb +12 -10
  114. data/lib/ddr/utils.rb +15 -28
  115. data/lib/ddr/vocab.rb +17 -15
  116. data/lib/ddr/vocab/asset.rb +17 -42
  117. data/lib/ddr/vocab/contact.rb +7 -5
  118. data/lib/ddr/vocab/display.rb +8 -6
  119. data/lib/ddr/vocab/duke_terms.rb +10 -8
  120. data/lib/ddr/vocab/rdf_vocabulary_parser.rb +39 -37
  121. data/lib/ddr/vocab/roles.rb +19 -17
  122. data/lib/ddr/vocab/sources/duketerms.rdf +8 -22
  123. data/lib/ddr/vocab/vocabulary.rb +26 -26
  124. data/spec/auth/ability_factory_spec.rb +1 -18
  125. data/spec/auth/ability_spec.rb +15 -119
  126. data/spec/auth/effective_permissions_spec.rb +1 -1
  127. data/spec/auth/effective_roles_spec.rb +1 -1
  128. data/spec/auth/ldap_gateway_spec.rb +9 -0
  129. data/spec/contacts/contacts_spec.rb +26 -0
  130. data/spec/controllers/including_role_based_access_controls_enforcement_spec.rb +5 -5
  131. data/spec/derivatives/multires_image_spec.rb +48 -0
  132. data/spec/derivatives/png_generator_spec.rb +8 -13
  133. data/spec/derivatives/ptif_generator_spec.rb +11 -9
  134. data/spec/derivatives/thumbnail_spec.rb +48 -0
  135. data/spec/dummy/config/environments/test.rb +1 -1
  136. data/spec/dummy/db/schema.rb +23 -25
  137. data/spec/factories/attachment_factories.rb +2 -2
  138. data/spec/factories/collection_factories.rb +2 -3
  139. data/spec/factories/component_factories.rb +2 -2
  140. data/spec/factories/item_factories.rb +2 -2
  141. data/spec/factories/structure_factories.rb +2 -8
  142. data/spec/factories/test_model_factories.rb +12 -4
  143. data/spec/fixtures/fits/document.xml +44 -42
  144. data/spec/fixtures/fits/image.xml +41 -42
  145. data/spec/helpers/models_helper_spec.rb +11 -0
  146. data/spec/index/filter_spec.rb +30 -208
  147. data/spec/index/filters_spec.rb +17 -0
  148. data/spec/index/query_spec.rb +10 -82
  149. data/spec/jobs/fits_file_characterization_spec.rb +52 -0
  150. data/spec/managers/derivatives_manager_spec.rb +105 -107
  151. data/spec/managers/technical_metadata_manager_spec.rb +27 -34
  152. data/spec/models/active_fedora_base_spec.rb +105 -5
  153. data/spec/models/active_fedora_datastream_spec.rb +39 -106
  154. data/spec/models/admin_set_spec.rb +10 -43
  155. data/spec/models/attachment_spec.rb +2 -3
  156. data/spec/models/collection_spec.rb +11 -225
  157. data/spec/models/component_spec.rb +4 -106
  158. data/spec/models/descriptive_metadata_spec.rb +38 -0
  159. data/spec/models/effective_license_spec.rb +64 -0
  160. data/spec/models/events_spec.rb +59 -52
  161. data/spec/models/file_management_spec.rb +13 -113
  162. data/spec/models/finding_aid_spec.rb +8 -31
  163. data/spec/models/has_admin_metadata_spec.rb +122 -131
  164. data/spec/models/has_children_spec.rb +3 -3
  165. data/spec/models/has_struct_metadata_spec.rb +37 -50
  166. data/spec/models/indexing_spec.rb +23 -160
  167. data/spec/models/item_spec.rb +2 -133
  168. data/spec/models/license_spec.rb +24 -0
  169. data/spec/models/solr_document_spec.rb +47 -236
  170. data/spec/models/struct_div_spec.rb +70 -0
  171. data/spec/models/structure_spec.rb +11 -89
  172. data/spec/models/target_spec.rb +2 -4
  173. data/spec/models/year_facet_spec.rb +23 -50
  174. data/spec/spec_helper.rb +13 -17
  175. data/spec/support/ezid_mock_identifier.rb +2 -2
  176. data/spec/support/shared_examples_for_auth_contexts.rb +0 -33
  177. data/spec/support/shared_examples_for_ddr_models.rb +94 -142
  178. data/spec/support/shared_examples_for_describables.rb +36 -31
  179. data/spec/support/shared_examples_for_governables.rb +2 -3
  180. data/spec/support/shared_examples_for_has_content.rb +46 -101
  181. data/spec/support/shared_examples_for_indexing.rb +6 -6
  182. data/spec/support/shared_examples_for_non_collection_models.rb +1 -32
  183. data/spec/support/structural_metadata_helper.rb +59 -230
  184. data/spec/utils_spec.rb +2 -0
  185. metadata +96 -229
  186. data/.ruby-version +0 -1
  187. data/config/initializers/rsolr_monkey_patches.rb +0 -7
  188. data/config/initializers/rubydora_monkey_patch.rb +0 -11
  189. data/config/locales/ddr-models.en.yml +0 -81
  190. data/db/migrate/20161021201011_add_permanent_id_to_events.rb +0 -8
  191. data/lib/ddr/auth/ability_definitions/admin_set_ability_definitions.rb +0 -9
  192. data/lib/ddr/auth/ability_definitions/lock_ability_definitions.rb +0 -13
  193. data/lib/ddr/auth/ability_definitions/publication_ability_definitions.rb +0 -16
  194. data/lib/ddr/datastreams/administrative_metadata_datastream.rb +0 -75
  195. data/lib/ddr/datastreams/caption_datastream.rb +0 -5
  196. data/lib/ddr/datastreams/content_datastream.rb +0 -17
  197. data/lib/ddr/datastreams/delete_external_files.rb +0 -29
  198. data/lib/ddr/datastreams/external_file_datastream.rb +0 -80
  199. data/lib/ddr/datastreams/intermediate_file_datastream.rb +0 -5
  200. data/lib/ddr/datastreams/multires_image_datastream.rb +0 -5
  201. data/lib/ddr/datastreams/streamable_media_datastream.rb +0 -5
  202. data/lib/ddr/derivatives/png_generator.rb +0 -17
  203. data/lib/ddr/derivatives/ptif_generator.rb +0 -55
  204. data/lib/ddr/derivatives/update_derivatives.rb +0 -25
  205. data/lib/ddr/events/deaccession_event.rb +0 -8
  206. data/lib/ddr/index/field_attribute.rb +0 -22
  207. data/lib/ddr/index/query_params.rb +0 -40
  208. data/lib/ddr/index/sort_order.rb +0 -28
  209. data/lib/ddr/models/cache.rb +0 -20
  210. data/lib/ddr/models/captionable.rb +0 -37
  211. data/lib/ddr/models/contact.rb +0 -23
  212. data/lib/ddr/models/file_characterization.rb +0 -37
  213. data/lib/ddr/models/has_intermediate_file.rb +0 -41
  214. data/lib/ddr/models/language.rb +0 -31
  215. data/lib/ddr/models/media_type.rb +0 -22
  216. data/lib/ddr/models/permanent_id.rb +0 -240
  217. data/lib/ddr/models/rights_statement.rb +0 -25
  218. data/lib/ddr/models/streamable.rb +0 -37
  219. data/lib/ddr/models/structures/agent.rb +0 -49
  220. data/lib/ddr/models/structures/component_type_term.rb +0 -29
  221. data/lib/ddr/models/structures/div.rb +0 -64
  222. data/lib/ddr/models/structures/f_locat.rb +0 -54
  223. data/lib/ddr/models/structures/file.rb +0 -52
  224. data/lib/ddr/models/structures/file_grp.rb +0 -35
  225. data/lib/ddr/models/structures/file_sec.rb +0 -22
  226. data/lib/ddr/models/structures/fptr.rb +0 -31
  227. data/lib/ddr/models/structures/mets_hdr.rb +0 -37
  228. data/lib/ddr/models/structures/mptr.rb +0 -49
  229. data/lib/ddr/models/structures/struct_map.rb +0 -40
  230. data/lib/ddr/models/with_content_file.rb +0 -37
  231. data/spec/datastreams/external_file_datastream_spec.rb +0 -48
  232. data/spec/dummy/config/structure_component_type.yml +0 -18
  233. data/spec/fixtures/abcd1234.vtt +0 -38
  234. data/spec/fixtures/arrow1rightred_e0.gif +0 -0
  235. data/spec/fixtures/extractedText1.txt +0 -1
  236. data/spec/fixtures/extractedText2.txt +0 -1
  237. data/spec/fixtures/extractedText3.txt +0 -3
  238. data/spec/fixtures/imageA.jpg +0 -0
  239. data/spec/fixtures/imageB.jpg +0 -0
  240. data/spec/index/csv_query_result_spec.rb +0 -44
  241. data/spec/index/fields_spec.rb +0 -380
  242. data/spec/index/query_builder_spec.rb +0 -140
  243. data/spec/index/query_clause_spec.rb +0 -68
  244. data/spec/models/cache_spec.rb +0 -32
  245. data/spec/models/contact_spec.rb +0 -56
  246. data/spec/models/descriptive_metadata_datastream_spec.rb +0 -139
  247. data/spec/models/file_characterization_spec.rb +0 -39
  248. data/spec/models/language_spec.rb +0 -59
  249. data/spec/models/media_type_spec.rb +0 -46
  250. data/spec/models/permanent_id_spec.rb +0 -432
  251. data/spec/models/rights_statement_spec.rb +0 -55
  252. data/spec/models/structures/agent_spec.rb +0 -30
  253. data/spec/models/structures/component_type_term_spec.rb +0 -14
  254. data/spec/models/structures/div_spec.rb +0 -26
  255. data/spec/models/structures/f_locat_spec.rb +0 -78
  256. data/spec/models/structures/file_grp_spec.rb +0 -23
  257. data/spec/models/structures/file_sec_spec.rb +0 -22
  258. data/spec/models/structures/file_spec.rb +0 -60
  259. data/spec/models/structures/fptr_spec.rb +0 -23
  260. data/spec/models/structures/mets_hdr_spec.rb +0 -26
  261. data/spec/models/structures/mptr_spec.rb +0 -25
  262. data/spec/models/structures/struct_map_spec.rb +0 -24
  263. data/spec/models/with_content_file_spec.rb +0 -37
  264. data/spec/support/shared_examples_for_associations.rb +0 -8
  265. data/spec/support/shared_examples_for_captionable.rb +0 -23
  266. data/spec/support/shared_examples_for_has_intermediate_file.rb +0 -28
  267. data/spec/support/shared_examples_for_publication.rb +0 -43
  268. data/spec/support/shared_examples_for_streamable_media.rb +0 -23
@@ -0,0 +1,32 @@
1
+ module Ddr::Models
2
+ #
3
+ # Maps vocabulary terms to names
4
+ #
5
+ class MetadataMapper
6
+ extend MetadataMappers
7
+
8
+ attr_reader :mapping
9
+
10
+ # param vocab [MetadataVocabulary] the vocabulary
11
+ def initialize(vocab)
12
+ @mapping = vocab.terms.each_with_object({}) do |term, memo|
13
+ memo[term.qualified_name] = term
14
+ end
15
+ end
16
+
17
+ def terms
18
+ mapping.values
19
+ end
20
+
21
+ def unqualified_names
22
+ mapping.values.map(&:unqualified_name)
23
+ end
24
+
25
+ def merge(other)
26
+ merged = self.dup
27
+ merged.mapping.merge! other.mapping
28
+ merged
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,18 @@
1
+ module Ddr::Models
2
+ # A registry of common metadata mappers
3
+ module MetadataMappers
4
+
5
+ def dc11
6
+ MetadataMapper.new(MetadataVocabulary.dc11)
7
+ end
8
+
9
+ def dcterms
10
+ MetadataMapper.new(MetadataVocabulary.dcterms)
11
+ end
12
+
13
+ def duketerms
14
+ MetadataMapper.new(MetadataVocabulary.duketerms)
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ require "delegate"
2
+
3
+ module Ddr::Models
4
+ # Wraps an RDF term (RDF::Vocabulary::Term)
5
+ class MetadataTerm < SimpleDelegator
6
+
7
+ def qualified_name
8
+ qname.join("_").to_sym
9
+ end
10
+
11
+ def unqualified_name
12
+ qname.last
13
+ end
14
+
15
+ def predicate
16
+ to_uri
17
+ end
18
+
19
+ def prefix
20
+ qname.first
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ module Ddr::Models
2
+ # Registry of common metadata vocabularies
3
+ module MetadataVocabularies
4
+
5
+ def dc11
6
+ MetadataVocabulary.new(RDF::DC11)
7
+ end
8
+
9
+ def dcterms
10
+ MetadataVocabulary.new(RDF::DC, except: RDF::DC.license)
11
+ end
12
+
13
+ def duketerms
14
+ MetadataVocabulary.new(Ddr::Vocab::DukeTerms)
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ module Ddr::Models
2
+ class MetadataVocabulary
3
+ extend MetadataVocabularies
4
+
5
+ attr_reader :rdf_vocab, :except, :only_properties
6
+
7
+ # @param rdf_vocab [RDF::Vocabulary] an RDF vocabulary class
8
+ # @param except [RDF::Vocabulary::Term, Array<RDF::Vocabulary::Term>] term(s) to exclude
9
+ # @param only_properties [Boolean] whether to include only RDF properties
10
+ # -- i.e., having RDF type http://www.w3.org/1999/02/22-rdf-syntax-ns#Property
11
+ # -- default: true
12
+ def initialize(rdf_vocab, except: nil, only_properties: true)
13
+ @rdf_vocab = rdf_vocab
14
+ @except = Array(except)
15
+ @only_properties = only_properties
16
+ end
17
+
18
+ # @return [Array<RDF::Vocabulary::Term>]
19
+ def terms
20
+ @terms ||= rdf_properties.map { |term| MetadataTerm.new(term) }
21
+ end
22
+
23
+ private
24
+
25
+ def rdf_properties
26
+ props = rdf_vocab.properties
27
+ if only_properties
28
+ props.select! { |prop| prop.type.include?("http://www.w3.org/1999/02/22-rdf-syntax-ns#Property") }
29
+ end
30
+ props - except
31
+ end
32
+
33
+ end
34
+ end
@@ -3,9 +3,6 @@ require 'json'
3
3
  module Ddr::Models
4
4
  module SolrDocument
5
5
  extend ActiveSupport::Concern
6
- extend Deprecation
7
-
8
- self.deprecation_horizon = 'ddr-models v3.0'
9
6
 
10
7
  included do
11
8
  alias_method :pid, :id
@@ -15,20 +12,13 @@ module Ddr::Models
15
12
 
16
13
  module ClassMethods
17
14
  def find(pid_or_uri)
18
- query = Ddr::Index::Query.new { id pid_or_uri.sub(/\Ainfo:fedora\//, "") }
15
+ pid = pid_or_uri.sub(/\Ainfo:fedora\//, "")
16
+ query = Ddr::Index::QueryBuilder.build { |q| q.id(pid) }
19
17
  if doc = query.docs.first
20
18
  return doc
21
19
  end
22
20
  raise NotFound, "SolrDocument not found for \"#{pid_or_uri}\"."
23
21
  end
24
-
25
- def find_by_permanent_id(ark)
26
- query = Ddr::Index::Query.new { where permanent_id: ark }
27
- if doc = query.docs.first
28
- return doc
29
- end
30
- raise NotFound, "SolrDocument not found for permanent id \"#{ark}\"."
31
- end
32
22
  end
33
23
 
34
24
  def inspect
@@ -141,14 +131,6 @@ module Ddr::Models
141
131
  has_datastream?(Ddr::Datastreams::CONTENT)
142
132
  end
143
133
 
144
- def has_intermediate_file?
145
- has_datastream?(Ddr::Datastreams::INTERMEDIATE_FILE)
146
- end
147
-
148
- def has_extracted_text?
149
- has_datastream?(Ddr::Datastreams::EXTRACTED_TEXT)
150
- end
151
-
152
134
  def content_ds
153
135
  datastreams[Ddr::Datastreams::CONTENT]
154
136
  end
@@ -183,20 +165,22 @@ module Ddr::Models
183
165
  active_fedora_model.tableize
184
166
  end
185
167
 
186
- def rights_statement
187
- @rights_statement ||= RightsStatement.call(self)
168
+ def effective_license
169
+ @effective_license ||= EffectiveLicense.call(self)
188
170
  end
189
- alias_method :effective_license, :rights_statement
190
- deprecation_deprecate :effective_license
191
171
 
192
172
  def roles
193
173
  @roles ||= Ddr::Auth::Roles::DetachedRoleSet.from_json(access_role)
194
174
  end
195
175
 
196
- def structure
197
- JSON.parse(fetch(Ddr::Index::Fields::STRUCTURE))
176
+ def struct_maps
177
+ JSON.parse(fetch(Ddr::Index::Fields::STRUCT_MAPS))
198
178
  rescue
199
- nil
179
+ {}
180
+ end
181
+
182
+ def struct_map(type='default')
183
+ struct_maps.present? ? struct_maps.fetch(type) : nil
200
184
  end
201
185
 
202
186
  def effective_permissions(agents)
@@ -205,7 +189,7 @@ module Ddr::Models
205
189
 
206
190
  def research_help
207
191
  research_help_contact = self[Ddr::Index::Fields::RESEARCH_HELP_CONTACT] || inherited_research_help_contact
208
- Ddr::Models::Contact.call(research_help_contact) if research_help_contact
192
+ Ddr::Contacts.get(research_help_contact) if research_help_contact
209
193
  end
210
194
 
211
195
  def parent_uri
@@ -222,12 +206,8 @@ module Ddr::Models
222
206
  end
223
207
  end
224
208
 
225
- def multires_image_file_paths
226
- if structure
227
- structure_docs.map { |doc| doc.multires_image_file_path }.compact
228
- else
229
- []
230
- end
209
+ def multires_image_file_paths(type='default')
210
+ struct_map_docs(type).map { |doc| doc.multires_image_file_path }.compact
231
211
  end
232
212
 
233
213
  # DRY HasAdminMetadata
@@ -237,92 +217,6 @@ module Ddr::Models
237
217
  end
238
218
  end
239
219
 
240
- def intermediate_type
241
- if has_intermediate_file?
242
- datastreams[Ddr::Datastreams::INTERMEDIATE_FILE]["dsMIME"]
243
- end
244
- end
245
-
246
- def intermediate_path
247
- if has_intermediate_file?
248
- Ddr::Utils.path_from_uri(datastreams[Ddr::Datastreams::INTERMEDIATE_FILE]["dsLocation"])
249
- end
250
- end
251
-
252
- def intermediate_extension
253
- if has_intermediate_file?
254
- extensions = Ddr::Models.preferred_file_extensions
255
- if extensions.include? intermediate_type
256
- extensions[intermediate_type]
257
- else
258
- intermediate_extension_default
259
- end
260
- end
261
- end
262
-
263
- def captionable?
264
- has_datastream?(Ddr::Datastreams::CAPTION)
265
- end
266
-
267
- def caption_type
268
- if captionable?
269
- datastreams[Ddr::Datastreams::CAPTION]["dsMIME"]
270
- end
271
- end
272
-
273
- def caption_extension
274
- if captionable?
275
- extensions = Ddr::Models.preferred_file_extensions
276
- if extensions.include? caption_type
277
- extensions[caption_type]
278
- else
279
- caption_extension_default
280
- end
281
- end
282
- end
283
-
284
- def caption_path
285
- if captionable?
286
- Ddr::Utils.path_from_uri(datastreams[Ddr::Datastreams::CAPTION]["dsLocation"])
287
- end
288
- end
289
-
290
- def streamable?
291
- has_datastream?(Ddr::Datastreams::STREAMABLE_MEDIA)
292
- end
293
-
294
- def streamable_media_extension
295
- if streamable?
296
- extensions = Ddr::Models.preferred_file_extensions
297
- if extensions.include? streamable_media_type
298
- extensions[streamable_media_type]
299
- else
300
- streamable_media_extension_default
301
- end
302
- end
303
- end
304
-
305
- def streamable_media_type
306
- if streamable?
307
- datastreams[Ddr::Datastreams::STREAMABLE_MEDIA]["dsMIME"]
308
- end
309
- end
310
-
311
- def streamable_media_path
312
- if streamable?
313
- Ddr::Utils.path_from_uri(datastreams[Ddr::Datastreams::STREAMABLE_MEDIA]["dsLocation"])
314
- end
315
- end
316
-
317
- # FIXME - Probably need a more general solution mapping object reader methods to index field names.
318
- def rights
319
- self["rights_tesim"]
320
- end
321
-
322
- def children
323
- children_query.docs rescue []
324
- end
325
-
326
220
  private
327
221
 
328
222
  def targets_query
@@ -355,45 +249,19 @@ module Ddr::Models
355
249
  end
356
250
  end
357
251
 
358
- def structure_docs
359
- structure_repo_ids.map { |repo_id| self.class.find(repo_id) }.compact
360
- end
361
-
362
- # For simplicity, initial implementation returns repo ID's only from top-level
363
- # (i.e., not nested) contents. This is done since we have not clarified what
364
- # an _ordered_ list of repo ID's should look like if structure contains nested
365
- # contents.
366
- def structure_repo_ids
367
- default_struct_map['contents'].map { |content| content['contents'].map { |content| content['repo_id'] } }.flatten
368
- end
369
-
370
- def default_struct_map
371
- structure['default'] || structure.values.first
372
- end
373
-
374
- def intermediate_extension_default
375
- datastreams[Ddr::Datastreams::INTERMEDIATE_FILE].default_file_extension
376
- end
377
-
378
- def caption_extension_default
379
- datastreams[Ddr::Datastreams::CAPTION].default_file_extension
252
+ def struct_map_docs(type='default')
253
+ struct_map_pids(type).map { |pid| self.class.find(pid) }.compact
380
254
  end
381
255
 
382
- def streamable_media_extension_default
383
- datastreams[Ddr::Datastreams::STREAMABLE_MEDIA].default_file_extension
256
+ # For simplicity, initial implementation returns PID's only from top-level
257
+ # (i.e., not nested) div's. This is done since we have not clarified what
258
+ # an _ordered_ list of PID's should look like if struct map contains nested
259
+ # div's.
260
+ def struct_map_pids(type='default')
261
+ struct_map(type)['divs'].map { |d| d['fptrs'].present? ? d['fptrs'].first : nil}.compact
262
+ rescue
263
+ []
384
264
  end
385
265
 
386
- def children_query
387
- case self[Ddr::Index::Fields::ACTIVE_FEDORA_MODEL]
388
- when 'Collection'
389
- Ddr::Index::Query.build(self) do |parent|
390
- is_member_of_collection parent.id
391
- end
392
- when 'Item'
393
- Ddr::Index::Query.build(self) do |parent|
394
- is_part_of parent.id
395
- end
396
- end
397
- end
398
266
  end
399
267
  end
@@ -0,0 +1,63 @@
1
+ module Ddr
2
+ module Models
3
+ class StructDiv
4
+
5
+ attr_accessor :id, :label, :order, :orderlabel, :type, :fptrs, :divs
6
+
7
+ def initialize(structmap_or_div_node)
8
+ @id = structmap_or_div_node['ID']
9
+ @label = structmap_or_div_node['LABEL']
10
+ @order = structmap_or_div_node['ORDER']
11
+ @orderlabel = structmap_or_div_node['ORDERLABEL']
12
+ @type = structmap_or_div_node['TYPE']
13
+ @fptrs = fptr_pids(structmap_or_div_node) if structmap_or_div_node.node_name == "div"
14
+ @divs = subdivs(structmap_or_div_node).sort
15
+ end
16
+
17
+ def <=>(other)
18
+ self.order.to_i <=> other.order.to_i
19
+ end
20
+
21
+ def pids
22
+ collect_pids(self)
23
+ end
24
+
25
+ def docs
26
+ query = ActiveFedora::SolrService.construct_query_for_pids(pids)
27
+ results = ActiveFedora::SolrService.query(query, rows: 999999)
28
+ results.each_with_object({}) do |r, memo|
29
+ memo[r["id"]] = ::SolrDocument.new(r)
30
+ end
31
+ end
32
+
33
+ def objects
34
+ pids.each_with_object({}) do |pid, memo|
35
+ memo[pid] = ActiveFedora::Base.find(pid)
36
+ end
37
+ end
38
+
39
+ def as_json(options={})
40
+ super.compact
41
+ end
42
+
43
+ private
44
+
45
+ def fptr_pids(div_node)
46
+ div_node.xpath('xmlns:fptr').map { |fptr_node| fptr_node["CONTENTIDS"].gsub('info:fedora/', '') }
47
+ end
48
+
49
+ def subdivs(structmap_or_div_node)
50
+ structmap_or_div_node.xpath('xmlns:div').map { |div_node| Ddr::Models::StructDiv.new(div_node) }
51
+ end
52
+
53
+ def collect_pids(structdiv)
54
+ pids = structdiv.divs.each_with_object([]) do |div, memo|
55
+ memo << collect_pids(div)
56
+ end
57
+ pids << structdiv.fptrs if structdiv.fptrs
58
+ pids.flatten
59
+ end
60
+
61
+ end
62
+ end
63
+ end
@@ -1,188 +1,52 @@
1
- module Ddr::Models
2
- #
3
- # Wraps a Nokogiri (XML) 'mets' Document
4
- #
5
- class Structure < SimpleDelegator
6
-
7
- # Indicates whether the structure is externally provided or maintained by the repository itself (i.e., is the
8
- # default structure for the object).
9
- EXTERNALLY_PROVIDED = 'provided'.freeze
10
- REPOSITORY_MAINTAINED = 'repository'.freeze
11
-
12
- TYPE_DEFAULT = 'default'.freeze
13
-
14
- # Based on the PCDM Extension 'Use' ontology -- https://github.com/duraspace/pcdm/blob/master/pcdm-ext/use.rdf
15
- USE_EXTRACTED_TEXT = 'ExtractedText'.freeze
16
- USE_INTERMEDIATE_FILE = 'IntermediateFile'.freeze
17
- USE_ORIGINAL_FILE = 'OriginalFile'.freeze
18
- USE_PRESERVATION_MASTER_FILE = 'PreservationMasterFile'.freeze
19
- USE_SERVICE_FILE = 'ServiceFile'.freeze
20
- USE_THUMBNAIL_IMAGE = 'ThumbnailImage'.freeze
21
- USE_TRANSCRIPT = 'Transcript'.freeze
22
-
23
- def filesec
24
- @filesec ||= Ddr::Models::Structures::FileSec.new(fileSec_node)
25
- end
26
-
27
- def files
28
- @files ||= collect_files
29
- end
30
-
31
- def uses
32
- @uses ||= collect_uses
33
- end
34
-
35
- def structmap(type=nil)
36
- sm = type ? structMap_node(type) : structMap_nodes.first
37
- @structmap ||= Ddr::Models::Structures::StructMap.new(sm)
38
- end
39
-
40
- def structmaps
41
- @structmaps ||= structMap_nodes.map { |sm| Ddr::Models::Structures::StructMap.new(sm) }
42
- end
43
-
44
- def metshdr
45
- @metshdr ||= Ddr::Models::Structures::MetsHdr.new(metsHdr_node)
46
- end
47
-
48
- def creator
49
- @creator ||= metshdr.empty? ? nil
50
- : Ddr::Models::Structures::MetsHdr.new(metsHdr_node).agents.first.name
51
- end
52
-
53
- def repository_maintained?
54
- creator == Ddr::Models::Structures::Agent::NAME_REPOSITORY_DEFAULT
55
- end
56
-
57
- def dereferenced_structure
58
- deref_struct = {}
59
- structmaps.each do |sm|
60
- deref_struct[sm.type] = sm.dereferenced_hash
1
+ module Ddr
2
+ module Models
3
+ #
4
+ # Wraps a Nokogiri (XML) Document
5
+ #
6
+ class Structure < SimpleDelegator
7
+
8
+ def initialize(xml_doc=nil)
9
+ super
61
10
  end
62
- deref_struct
63
- end
64
-
65
- def as_xml_document
66
- __getobj__
67
- end
68
-
69
- def add_metshdr(id:nil, createdate:nil, lastmoddate:nil, recordstatus:nil)
70
- metshdr = Ddr::Models::Structures::MetsHdr.build(id: id, createdate: createdate, lastmoddate: lastmoddate,
71
- recordstatus: recordstatus, document: as_xml_document)
72
- root.add_child(metshdr)
73
- metshdr
74
- end
75
-
76
- def add_agent(parent:, id:nil, role:, otherrole:nil, type:nil, othertype:nil, name:nil)
77
- agent = Ddr::Models::Structures::Agent.build(id: id, role: role, otherrole: otherrole, type: type,
78
- othertype: othertype, name: name, document: as_xml_document)
79
- parent.add_child(agent)
80
- agent
81
- end
82
-
83
- def add_filesec(id:nil)
84
- filesec = Ddr::Models::Structures::FileSec.build(id: id, document: as_xml_document)
85
- root.add_child(filesec)
86
- filesec
87
- end
88
11
 
89
- def add_filegrp(parent:, id:nil, use:nil)
90
- filegrp = Ddr::Models::Structures::FileGrp.build(id: id, use: use, document: as_xml_document)
91
- parent.add_child(filegrp)
92
- filegrp
93
- end
94
-
95
- def add_file(parent:, id:SecureRandom.uuid, use:nil)
96
- file = Ddr::Models::Structures::File.build(id: id, use: use, document: as_xml_document)
97
- parent.add_child(file)
98
- file
99
- end
100
-
101
- def add_flocat(parent:, id:nil, loctype:'ARK', otherloctype: nil, use:nil, href:)
102
- flocat = Ddr::Models::Structures::FLocat.build(id: id, loctype: loctype, otherloctype: otherloctype, use: use,
103
- href: href, document: as_xml_document)
104
- parent.add_child(flocat)
105
- flocat
106
- end
107
-
108
- def add_structmap(id:nil, label:nil, type:)
109
- structmap = Ddr::Models::Structures::StructMap.build(id: id, label: label, type: type, document: as_xml_document)
110
- root.add_child(structmap)
111
- structmap
112
- end
113
-
114
- def add_div(parent:, id:nil, label:nil, order:nil, orderlabel: nil, type:nil)
115
- div = Ddr::Models::Structures::Div.build(id: id, label: label, order:order, orderlabel: orderlabel, type: type,
116
- document: as_xml_document)
117
- parent.add_child(div)
118
- div
119
- end
120
-
121
- def add_fptr(parent:, id: nil, fileid:)
122
- fptr = Ddr::Models::Structures::Fptr.build(id: id, fileid: fileid, document: as_xml_document)
123
- parent.add_child(fptr)
124
- fptr
125
- end
126
-
127
- def add_mptr(parent:, id: nil, loctype:'ARK', otherloctype: nil, href:)
128
- mptr = Ddr::Models::Structures::Mptr.build(id: id, loctype: loctype, otherloctype: otherloctype, href: href,
129
- document: as_xml_document)
130
- parent.add_child(mptr)
131
- mptr
132
- end
133
-
134
- private
135
-
136
- def fileSec_node
137
- xpath("//xmlns:fileSec").first
138
- end
139
-
140
- def structMap_nodes
141
- xpath("//xmlns:structMap")
142
- end
12
+ def struct_maps
13
+ @struct_maps ||= build_struct_maps(structMap_nodes)
14
+ end
143
15
 
144
- def structMap_node(type)
145
- xpath("//xmlns:structMap[@TYPE='#{type}']").first
146
- end
16
+ def structMap_node(type='default')
17
+ xpath("//xmlns:structMap[@TYPE='#{type}']").first
18
+ end
147
19
 
148
- def metsHdr_node
149
- xpath("//xmlns:metsHdr")
150
- end
20
+ def as_xml_document
21
+ __getobj__
22
+ end
151
23
 
152
- def file_nodes
153
- xpath("//xmlns:file")
154
- end
24
+ private
155
25
 
156
- def flocat_nodes
157
- xpath("//xmlns:FLocat")
158
- end
26
+ def structMap_nodes
27
+ xpath("//xmlns:structMap")
28
+ end
159
29
 
160
- def collect_files
161
- files = {}
162
- file_nodes.each do |file_node|
163
- file = Ddr::Models::Structures::File.new(file_node)
164
- files[file.id] = file
30
+ def build_struct_maps(structMap_nodes)
31
+ smaps = {}
32
+ structMap_nodes.each do |structMap_node|
33
+ type = structMap_node['TYPE'] || 'default'
34
+ raise StandardError, "Multiple '#{type}' structMaps" if smaps[type].present?
35
+ smaps[type] = Ddr::Models::StructDiv.new(structMap_node)
36
+ end
37
+ smaps
165
38
  end
166
- files
167
- end
168
39
 
169
- def collect_uses
170
- uses = {}
171
- flocat_nodes.each do |flocat_node|
172
- flocat = Ddr::Models::Structures::FLocat.new(flocat_node)
173
- uses[flocat.effective_use] ||= []
174
- uses[flocat.effective_use] << flocat
40
+ def self.template
41
+ Nokogiri::XML(
42
+ '<mets xmlns="http://www.loc.gov/METS/" xmlns:xlink="http://www.w3.org/1999/xlink">
43
+ <structMap TYPE="default" />
44
+ </mets>'
45
+ ) do |config|
46
+ config.noblanks
47
+ end
175
48
  end
176
- uses
177
- end
178
49
 
179
- def self.xml_template
180
- Nokogiri::XML(
181
- '<mets xmlns="http://www.loc.gov/METS/" xmlns:xlink="http://www.w3.org/1999/xlink" />'
182
- ) do |config|
183
- config.noblanks
184
- end
185
50
  end
186
-
187
51
  end
188
- end
52
+ end