hyrax 3.0.0.pre.rc4 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (271) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +41 -8
  3. data/.dassie/Gemfile +10 -5
  4. data/.dassie/config/cable.yml +1 -1
  5. data/.dassie/config/environments/development.rb +2 -0
  6. data/.dassie/config/environments/production.rb +1 -1
  7. data/.dassie/config/initializers/hyrax.rb +5 -0
  8. data/.dassie/config/initializers/riiif.rb +22 -20
  9. data/.dassie/config/redis.yml +1 -0
  10. data/.dassie/config/role_map.yml +2 -0
  11. data/.dassie/db/seeds.rb +9 -1
  12. data/.dassie/package.json +3 -5
  13. data/.dockerignore +4 -0
  14. data/.env +1 -2
  15. data/.rubocop.yml +4 -0
  16. data/CONTAINERS.md +21 -1
  17. data/Dockerfile +46 -17
  18. data/Gemfile +21 -27
  19. data/app/actors/hyrax/actors/base_actor.rb +1 -1
  20. data/app/actors/hyrax/actors/create_with_remote_files_actor.rb +89 -41
  21. data/app/actors/hyrax/actors/create_with_remote_files_ordered_members_actor.rb +7 -42
  22. data/app/actors/hyrax/actors/file_actor.rb +4 -2
  23. data/app/actors/hyrax/actors/file_set_actor.rb +18 -11
  24. data/app/controllers/concerns/hyrax/collections_controller_behavior.rb +20 -8
  25. data/app/controllers/concerns/hyrax/embargoes_controller_behavior.rb +21 -9
  26. data/app/controllers/concerns/hyrax/leases_controller_behavior.rb +14 -5
  27. data/app/controllers/concerns/hyrax/works_controller_behavior.rb +38 -8
  28. data/app/controllers/hyrax/admin/permission_template_accesses_controller.rb +0 -4
  29. data/app/controllers/hyrax/admin/workflows_controller.rb +8 -2
  30. data/app/controllers/hyrax/dashboard/collection_members_controller.rb +13 -9
  31. data/app/controllers/hyrax/dashboard/collections_controller.rb +14 -14
  32. data/app/controllers/hyrax/file_sets_controller.rb +49 -13
  33. data/app/controllers/hyrax/permissions_controller.rb +3 -4
  34. data/app/controllers/hyrax/workflow_actions_controller.rb +3 -1
  35. data/app/forms/hyrax/forms/collection_form.rb +12 -6
  36. data/app/forms/hyrax/forms/dashboard/nest_collection_form.rb +24 -2
  37. data/app/forms/hyrax/forms/file_set_form.rb +46 -0
  38. data/app/forms/hyrax/forms/permission.rb +23 -0
  39. data/app/forms/hyrax/forms/permission_template_form.rb +8 -2
  40. data/app/forms/hyrax/forms/resource_form.rb +31 -13
  41. data/app/forms/hyrax/forms/work_form.rb +5 -2
  42. data/app/helpers/hyrax/batch_edits_helper.rb +3 -1
  43. data/app/helpers/hyrax/collections_helper.rb +88 -2
  44. data/app/helpers/hyrax/dashboard_helper_behavior.rb +16 -5
  45. data/app/helpers/hyrax/embargo_helper.rb +4 -0
  46. data/app/helpers/hyrax/file_set_helper.rb +25 -6
  47. data/app/helpers/hyrax/hyrax_helper_behavior.rb +8 -0
  48. data/app/helpers/hyrax/lease_helper.rb +4 -0
  49. data/app/helpers/hyrax/url_helper.rb +4 -1
  50. data/app/helpers/hyrax/work_form_helper.rb +53 -0
  51. data/app/indexers/hyrax/administrative_set_indexer.rb +18 -0
  52. data/app/indexers/hyrax/valkyrie_file_set_indexer.rb +118 -0
  53. data/app/indexers/hyrax/valkyrie_indexer.rb +10 -4
  54. data/app/indexers/hyrax/valkyrie_work_indexer.rb +3 -1
  55. data/app/inputs/controlled_vocabulary_input.rb +2 -5
  56. data/app/jobs/attach_files_to_work_job.rb +19 -10
  57. data/app/jobs/attach_files_to_work_with_ordered_members_job.rb +6 -5
  58. data/app/jobs/embargo_expiry_job.rb +7 -5
  59. data/app/jobs/file_set_attached_event_job.rb +6 -1
  60. data/app/jobs/ingest_local_file_job.rb +18 -2
  61. data/app/jobs/inherit_permissions_job.rb +9 -5
  62. data/app/jobs/lease_expiry_job.rb +6 -4
  63. data/app/models/admin_set.rb +6 -25
  64. data/app/models/collection_branding_info.rb +25 -9
  65. data/app/models/concerns/hyrax/ability.rb +14 -1
  66. data/app/models/concerns/hyrax/collection_behavior.rb +17 -44
  67. data/app/models/concerns/hyrax/embargoable.rb +24 -0
  68. data/app/models/concerns/hyrax/file_set/characterization.rb +18 -12
  69. data/app/models/concerns/hyrax/solr_document_behavior.rb +9 -46
  70. data/app/models/concerns/hyrax/suppressible.rb +5 -0
  71. data/app/models/concerns/hyrax/user.rb +9 -3
  72. data/app/models/concerns/hyrax/work_behavior.rb +1 -1
  73. data/app/models/hyrax/file_set.rb +7 -0
  74. data/app/models/hyrax/pcdm_collection.rb +1 -0
  75. data/app/models/hyrax/permission_template.rb +98 -12
  76. data/app/models/hyrax/virus_scanner.rb +27 -18
  77. data/app/models/hyrax/work.rb +2 -0
  78. data/app/models/job_io_wrapper.rb +1 -1
  79. data/app/models/sipity/agent.rb +1 -0
  80. data/app/models/sipity/entity.rb +30 -8
  81. data/app/models/sipity/workflow.rb +1 -0
  82. data/app/models/sipity.rb +42 -0
  83. data/app/presenters/hyrax/admin_set_options_presenter.rb +12 -8
  84. data/app/presenters/hyrax/admin_set_presenter.rb +5 -1
  85. data/app/presenters/hyrax/admin_set_selection_presenter.rb +116 -0
  86. data/app/presenters/hyrax/collection_presenter.rb +41 -20
  87. data/app/presenters/hyrax/file_set_presenter.rb +6 -1
  88. data/app/presenters/hyrax/file_usage.rb +3 -2
  89. data/app/presenters/hyrax/pcdm_member_presenter_factory.rb +119 -0
  90. data/app/presenters/hyrax/stats_usage_presenter.rb +2 -1
  91. data/app/presenters/hyrax/trophy_presenter.rb +33 -4
  92. data/app/presenters/hyrax/user_profile_presenter.rb +11 -1
  93. data/app/presenters/hyrax/version_list_presenter.rb +19 -0
  94. data/app/presenters/hyrax/version_presenter.rb +3 -2
  95. data/app/presenters/hyrax/work_show_presenter.rb +30 -5
  96. data/app/presenters/hyrax/work_usage.rb +5 -3
  97. data/app/renderers/hyrax/renderers/attribute_renderer.rb +10 -2
  98. data/app/search_builders/hyrax/admin_set_search_builder.rb +1 -1
  99. data/app/search_builders/hyrax/collection_member_search_builder.rb +6 -1
  100. data/app/search_builders/hyrax/my/collections_search_builder.rb +2 -2
  101. data/app/search_builders/hyrax/nested_collections_parent_search_builder.rb +1 -1
  102. data/app/search_builders/hyrax/single_collection_search_builder.rb +1 -1
  103. data/app/services/hyrax/access_control_list.rb +1 -1
  104. data/app/services/hyrax/adapters/nesting_index_adapter.rb +1 -1
  105. data/app/services/hyrax/admin_set_create_service.rb +3 -1
  106. data/app/services/hyrax/collections/collection_member_search_service.rb +72 -0
  107. data/app/services/hyrax/collections/collection_member_service.rb +112 -27
  108. data/app/services/hyrax/collections/migration_service.rb +4 -2
  109. data/app/services/hyrax/collections/nested_collection_persistence_service.rb +12 -13
  110. data/app/services/hyrax/collections/nested_collection_query_service.rb +2 -0
  111. data/app/services/hyrax/collections/permissions_create_service.rb +6 -4
  112. data/app/services/hyrax/contextual_path.rb +24 -1
  113. data/app/services/hyrax/custom_queries/find_file_metadata.rb +7 -5
  114. data/app/services/hyrax/custom_queries/navigators/parent_collections_navigator.rb +46 -0
  115. data/app/services/hyrax/edit_permissions_service.rb +74 -41
  116. data/app/services/hyrax/embargo_manager.rb +1 -1
  117. data/app/services/hyrax/find_objects_via_solr_service.rb +31 -0
  118. data/app/services/hyrax/graph_exporter.rb +1 -1
  119. data/app/services/hyrax/listeners/member_cleanup_listener.rb +26 -0
  120. data/app/services/hyrax/listeners/metadata_index_listener.rb +18 -1
  121. data/app/services/hyrax/listeners/object_lifecycle_listener.rb +1 -1
  122. data/app/services/hyrax/listeners/trophy_cleanup_listener.rb +17 -0
  123. data/app/services/hyrax/listeners.rb +2 -0
  124. data/app/services/hyrax/multiple_membership_checker.rb +53 -29
  125. data/app/services/hyrax/persist_derivatives.rb +3 -1
  126. data/app/services/hyrax/resource_status.rb +7 -0
  127. data/app/services/hyrax/search_service.rb +4 -2
  128. data/app/services/hyrax/solr_query_builder_service.rb +45 -8
  129. data/app/services/hyrax/solr_query_service.rb +224 -0
  130. data/app/services/hyrax/solr_service.rb +8 -1
  131. data/app/services/hyrax/statistics/depositors/summary.rb +2 -1
  132. data/app/services/hyrax/thumbnail_path_service.rb +1 -1
  133. data/app/services/hyrax/versioning_service.rb +1 -1
  134. data/app/services/hyrax/visibility_intention.rb +20 -2
  135. data/app/services/hyrax/visibility_propagator.rb +30 -1
  136. data/app/services/hyrax/work_uploads_handler.rb +22 -4
  137. data/app/services/hyrax/workflow/actionable_objects.rb +70 -0
  138. data/app/services/hyrax/workflow/object_in_workflow_decorator.rb +31 -0
  139. data/app/services/hyrax/workflow/status_list_service.rb +43 -13
  140. data/app/views/hyrax/admin/admin_sets/_show_document_list_row.html.erb +1 -1
  141. data/app/views/hyrax/base/_form_child_work_relationships.html.erb +1 -1
  142. data/app/views/hyrax/base/_form_relationships.html.erb +1 -2
  143. data/app/views/hyrax/base/_form_rendering.html.erb +1 -1
  144. data/app/views/hyrax/base/_form_representative.html.erb +1 -1
  145. data/app/views/hyrax/base/_form_share.html.erb +1 -5
  146. data/app/views/hyrax/base/_form_thumbnail.html.erb +1 -1
  147. data/app/views/hyrax/base/_form_visibility_error.html.erb +2 -0
  148. data/app/views/hyrax/base/_guts4form.html.erb +3 -3
  149. data/app/views/hyrax/base/_representative_media.html.erb +1 -1
  150. data/app/views/hyrax/base/_show_actions.html.erb +2 -2
  151. data/app/views/hyrax/base/_work_button_row.html.erb +1 -1
  152. data/app/views/hyrax/base/_workflow_actions.html.erb +1 -1
  153. data/app/views/hyrax/batch_edits/edit.html.erb +2 -2
  154. data/app/views/hyrax/batch_uploads/_form.html.erb +1 -1
  155. data/app/views/hyrax/collections/_list_collections.html.erb +1 -1
  156. data/app/views/hyrax/collections/_search_form.html.erb +1 -1
  157. data/app/views/hyrax/collections/show.html.erb +1 -1
  158. data/app/views/hyrax/dashboard/collections/_form.html.erb +3 -3
  159. data/app/views/hyrax/dashboard/collections/_form_branding.html.erb +1 -1
  160. data/app/views/hyrax/dashboard/collections/_list_collections.html.erb +1 -1
  161. data/app/views/hyrax/dashboard/collections/edit.html.erb +4 -2
  162. data/app/views/hyrax/dashboard/collections/new.html.erb +4 -2
  163. data/app/views/hyrax/dashboard/collections/show.html.erb +1 -1
  164. data/app/views/hyrax/file_sets/_actions.html.erb +10 -0
  165. data/app/views/hyrax/file_sets/edit.html.erb +1 -1
  166. data/app/views/hyrax/file_sets/media_display/_audio.html.erb +1 -1
  167. data/app/views/hyrax/file_sets/media_display/_default.html.erb +1 -1
  168. data/app/views/hyrax/file_sets/media_display/_image.html.erb +1 -1
  169. data/app/views/hyrax/file_sets/media_display/_office_document.html.erb +1 -1
  170. data/app/views/hyrax/file_sets/media_display/_pdf.html.erb +1 -1
  171. data/app/views/hyrax/file_sets/media_display/_video.html.erb +1 -1
  172. data/app/views/hyrax/file_sets/show.html.erb +1 -1
  173. data/app/views/hyrax/my/_admin_set_action_menu.html.erb +0 -11
  174. data/app/views/hyrax/my/_collection_action_menu.html.erb +1 -2
  175. data/app/views/hyrax/my/collections/_list_collections.html.erb +1 -1
  176. data/app/views/hyrax/my/collections/_modal_add_subcollection.html.erb +3 -5
  177. data/app/views/hyrax/stats/file.html.erb +1 -1
  178. data/app/views/hyrax/stats/work.html.erb +1 -1
  179. data/app/views/hyrax/uploads/_js_templates.html.erb +4 -4
  180. data/app/views/hyrax/uploads/_js_templates_versioning.html.erb +4 -4
  181. data/app/views/hyrax/users/_contributions.html.erb +1 -1
  182. data/app/views/hyrax/users/_profile_tabs.html.erb +2 -2
  183. data/app/views/hyrax/users/_search_form.html.erb +1 -1
  184. data/app/views/hyrax/users/_user.html.erb +1 -1
  185. data/app/views/hyrax/users/_user_info.html.erb +9 -9
  186. data/bin/db-migrate-seed.sh +6 -2
  187. data/bin/hyrax-entrypoint.sh +0 -14
  188. data/bin/solrcloud-assign-configset.sh +35 -0
  189. data/bin/solrcloud-upload-configset.sh +42 -0
  190. data/chart/hyrax/Chart.yaml +12 -8
  191. data/chart/hyrax/README.md +94 -11
  192. data/chart/hyrax/templates/NOTES.txt +1 -1
  193. data/chart/hyrax/templates/_helpers.tpl +98 -0
  194. data/chart/hyrax/templates/branding-pvc.yaml +14 -0
  195. data/chart/hyrax/templates/configmap-env.yaml +21 -11
  196. data/chart/hyrax/templates/cron-embargo.yaml +24 -0
  197. data/chart/hyrax/templates/cron-lease.yaml +24 -0
  198. data/chart/hyrax/templates/deployment-worker.yaml +129 -0
  199. data/chart/hyrax/templates/deployment.yaml +125 -4
  200. data/chart/hyrax/templates/derivatives-pvc.yaml +14 -0
  201. data/chart/hyrax/templates/ingress.yaml +13 -4
  202. data/chart/hyrax/templates/secrets.yaml +12 -2
  203. data/chart/hyrax/templates/uploads-pvc.yaml +14 -0
  204. data/chart/hyrax/values.yaml +186 -2
  205. data/config/brakeman.ignore +2 -2
  206. data/config/features.rb +47 -43
  207. data/config/initializers/listeners.rb +4 -0
  208. data/config/initializers/valkryrie_storage.rb +7 -0
  209. data/config/locales/hyrax.de.yml +1 -1
  210. data/config/locales/hyrax.en.yml +1 -1
  211. data/config/locales/hyrax.es.yml +1 -1
  212. data/config/locales/hyrax.fr.yml +1 -1
  213. data/config/locales/hyrax.it.yml +1 -1
  214. data/config/locales/hyrax.pt-BR.yml +1 -1
  215. data/config/locales/hyrax.zh.yml +1 -1
  216. data/docker-compose.yml +39 -8
  217. data/documentation/developing-your-hyrax-based-app.md +4 -4
  218. data/documentation/legacyREADME.md +3 -3
  219. data/lib/generators/hyrax/templates/config/initializers/hyrax.rb +5 -0
  220. data/lib/generators/hyrax/templates/config/initializers/riiif.rb +22 -20
  221. data/lib/hyrax/active_fedora_dummy_model.rb +62 -0
  222. data/lib/hyrax/configuration.rb +28 -0
  223. data/lib/hyrax/engine.rb +3 -1
  224. data/lib/hyrax/errors.rb +2 -0
  225. data/lib/hyrax/resource_name.rb +1 -0
  226. data/lib/hyrax/specs/capybara.rb +5 -3
  227. data/lib/hyrax/specs/shared_specs/valkyrie_storage_versions.rb +9 -0
  228. data/lib/hyrax/transactions/container.rb +32 -1
  229. data/lib/hyrax/transactions/file_set_destroy.rb +21 -0
  230. data/lib/hyrax/transactions/steps/add_file_sets.rb +3 -2
  231. data/lib/hyrax/transactions/steps/add_to_parent.rb +36 -0
  232. data/lib/hyrax/transactions/steps/delete_resource.rb +38 -0
  233. data/lib/hyrax/transactions/steps/destroy_work.rb +1 -0
  234. data/lib/hyrax/transactions/steps/remove_file_set_from_work.rb +47 -0
  235. data/lib/hyrax/transactions/work_create.rb +2 -1
  236. data/lib/hyrax/transactions/work_destroy.rb +20 -0
  237. data/lib/hyrax/valkyrie_can_can_adapter.rb +3 -0
  238. data/lib/hyrax/valkyrie_simple_path_generator.rb +20 -0
  239. data/lib/hyrax/version.rb +1 -1
  240. data/lib/hyrax.rb +9 -0
  241. data/lib/tasks/collection_type_global_id.rake +1 -1
  242. data/lib/tasks/embargo_lease.rake +27 -0
  243. data/lib/tasks/regenerate_derivatives.rake +12 -0
  244. data/lib/wings/active_fedora_converter/default_work.rb +19 -0
  245. data/lib/wings/attribute_transformer.rb +29 -19
  246. data/lib/wings/converter_value_mapper.rb +2 -2
  247. data/lib/wings/model_transformer.rb +21 -20
  248. data/lib/wings/orm_converter.rb +42 -23
  249. data/lib/wings/setup.rb +2 -0
  250. data/lib/wings/valkyrie/persister.rb +8 -5
  251. data/lib/wings/valkyrie/query_service.rb +96 -41
  252. data/lib/wings/valkyrie/storage.rb +56 -1
  253. data/lib/wings.rb +0 -21
  254. data/template.rb +1 -1
  255. metadata +41 -21
  256. data/chart/fcrepo/.gitignore +0 -2
  257. data/chart/fcrepo/.helmignore +0 -23
  258. data/chart/fcrepo/Chart.yaml +0 -11
  259. data/chart/fcrepo/README.md +0 -50
  260. data/chart/fcrepo/templates/NOTES.txt +0 -21
  261. data/chart/fcrepo/templates/_helpers.tpl +0 -68
  262. data/chart/fcrepo/templates/configmap-env.yaml +0 -19
  263. data/chart/fcrepo/templates/deployment.yaml +0 -109
  264. data/chart/fcrepo/templates/ingress.yaml +0 -41
  265. data/chart/fcrepo/templates/pvc.yaml +0 -20
  266. data/chart/fcrepo/templates/secret.yaml +0 -12
  267. data/chart/fcrepo/templates/service.yaml +0 -15
  268. data/chart/fcrepo/templates/serviceaccount.yaml +0 -12
  269. data/chart/fcrepo/templates/tests/test-connection.yaml +0 -15
  270. data/chart/fcrepo/values.yaml +0 -79
  271. data/chart/hyrax/templates/fcrepo-secret.yaml +0 -13
@@ -73,7 +73,7 @@ module Wings
73
73
  end
74
74
 
75
75
  def result
76
- collections = value.last.map { |id| ActiveFedora::Base.find(id.id) }
76
+ collections = value.last.map { |id| ActiveFedora::Base.find(id.to_s) }
77
77
  [:member_of_collections, collections]
78
78
  end
79
79
  end
@@ -86,7 +86,7 @@ module Wings
86
86
  end
87
87
 
88
88
  def result
89
- members = value.last.map { |id| ActiveFedora::Base.find(id.id) }
89
+ members = value.last.map { |id| ActiveFedora::Base.find(id.to_s) }
90
90
  [:members, members]
91
91
  end
92
92
  end
@@ -110,39 +110,25 @@ module Wings
110
110
  private
111
111
 
112
112
  def mint_id
113
- id = pcdm_object.assign_id
113
+ id = pcdm_object.try(:assign_id)
114
114
 
115
115
  pcdm_object.id = id if id.present?
116
116
  end
117
117
 
118
118
  def attributes
119
- attribute_source = pcdm_object.try(:metadata_node) || pcdm_object
120
-
121
- all_keys =
122
- attribute_source.attributes.keys +
123
- OrmConverter.relationship_keys_for(reflections: pcdm_object.try(:reflections))
124
-
125
- result = AttributeTransformer.for(pcdm_object)
126
- .run(pcdm_object, all_keys)
127
- .merge(reflection_ids)
128
- .merge(additional_attributes)
119
+ transformer = AttributeTransformer.for(pcdm_object)
120
+ result = transformer.run(pcdm_object).merge(additional_attributes)
129
121
 
130
122
  append_embargo(result)
131
123
  append_lease(result)
124
+ append_permissions(result)
132
125
 
133
126
  result
134
127
  end
135
128
 
136
- def reflection_ids
137
- keys = pcdm_object.try(:reflections)&.keys || []
138
-
139
- keys.select { |k| k.to_s.end_with? '_id' }.each_with_object({}) do |k, mem|
140
- mem[k] = pcdm_object.try(k)
141
- end
142
- end
143
-
144
129
  def additional_attributes
145
- { :created_at => pcdm_object.try(:create_date),
130
+ { :id => pcdm_object.id,
131
+ :created_at => pcdm_object.try(:create_date),
146
132
  :updated_at => pcdm_object.try(:modified_date),
147
133
  :member_ids => member_ids,
148
134
  ::Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK => lock_token }
@@ -183,5 +169,20 @@ module Wings
183
169
 
184
170
  attrs[:lease] = Hyrax::Lease.new(**lease_attrs)
185
171
  end
172
+
173
+ def append_permissions(attrs)
174
+ return unless pcdm_object.try(:permissions)
175
+ attrs[:permissions] = pcdm_object.permissions.map do |permission|
176
+ agent = permission.type == 'group' ? "group/#{permission.agent_name}" : permission.agent_name
177
+
178
+ Hyrax::Permission.new(id: permission.id,
179
+ mode: permission.access.to_sym,
180
+ agent: agent,
181
+ access_to: ::Valkyrie::ID.new(permission.access_to_id),
182
+ new_record: permission.new_record?)
183
+ end
184
+
185
+ attrs[:access_to] = attrs[:permissions].find { |p| p.access_to&.id&.present? }&.access_to
186
+ end
186
187
  end
187
188
  end
@@ -2,20 +2,10 @@
2
2
 
3
3
  module Wings
4
4
  ##
5
+ # @api private
6
+ #
5
7
  # Transform AF object class to Valkyrie::Resource class representation.
6
8
  class OrmConverter
7
- ##
8
- # @param reflections [Hash<Symbol, Object>]
9
- #
10
- # @return [Array<Symbol>]
11
- def self.relationship_keys_for(reflections:)
12
- Hash(reflections).keys.map do |k|
13
- key_string = k.to_s
14
- next if key_string.include?('id') || key_string.include?('proxies')
15
- key_string.singularize + '_ids'
16
- end.compact
17
- end
18
-
19
9
  ##
20
10
  # Selects an existing base class for the generated valkyrie class
21
11
  #
@@ -39,9 +29,6 @@ module Wings
39
29
  # rubocop:disable Metrics/MethodLength because metaprogramming a class
40
30
  # results in long methods
41
31
  def self.to_valkyrie_resource_class(klass:)
42
- relationship_keys = klass.respond_to?(:reflections) ? relationship_keys_for(reflections: klass.reflections) : []
43
- reflection_id_keys = klass.respond_to?(:reflections) ? klass.reflections.keys.select { |k| k.to_s.end_with? '_id' } : []
44
-
45
32
  Class.new(base_for(klass: klass)) do
46
33
  # store a string we can resolve to the internal resource
47
34
  @internal_resource = klass.try(:to_rdf_representation) || klass.name
@@ -53,6 +40,12 @@ module Wings
53
40
  _canonical_valkyrie_model&.name
54
41
  end
55
42
 
43
+ ##
44
+ # @return [String]
45
+ def to_s
46
+ internal_resource
47
+ end
48
+
56
49
  ##
57
50
  # @api private
58
51
  def _canonical_valkyrie_model
@@ -60,8 +53,18 @@ module Wings
60
53
  end
61
54
  end
62
55
 
63
- def self.to_s
64
- internal_resource
56
+ ##
57
+ # @return [URI::GID]
58
+ def to_global_id
59
+ URI::GID.build([GlobalID.app, internal_resource, id, {}])
60
+ end
61
+
62
+ ##
63
+ # @return [ActiveModel::Base]
64
+ def to_model
65
+ model_class = internal_resource.safe_constantize || self
66
+
67
+ Hyrax::ActiveFedoraDummyModel.new(model_class, id)
65
68
  end
66
69
 
67
70
  klass.properties.each_key do |property_name|
@@ -74,14 +77,30 @@ module Wings
74
77
  end
75
78
  end
76
79
 
77
- relationship_keys.each do |linked_property_name|
78
- next if fields.include?(linked_property_name.to_sym)
79
- attribute linked_property_name.to_sym, ::Valkyrie::Types::Set.of(::Valkyrie::Types::ID)
80
+ # add reflection associations
81
+ ldp_reflections = (klass.try(:reflections) || []).select do |_key, reflection|
82
+ case reflection
83
+ when ActiveFedora::Reflection::FilterReflection,
84
+ ActiveFedora::Reflection::OrdersReflection,
85
+ ActiveFedora::Reflection::BasicContainsReflection,
86
+ ActiveFedora::Reflection::HasSubresourceReflection
87
+ false
88
+ else
89
+ true
90
+ end
80
91
  end
81
92
 
82
- reflection_id_keys.each do |property_name|
83
- next if fields.include?(property_name.to_sym)
84
- attribute property_name, ::Valkyrie::Types::ID
93
+ ldp_reflections.each do |reflection_key, reflection|
94
+ if reflection.collection?
95
+ type = ::Valkyrie::Types::Set.of(::Valkyrie::Types::ID)
96
+ attribute_name = (reflection_key.to_s.singularize + '_ids').to_sym
97
+ else
98
+ type = ::Valkyrie::Types::ID.optional
99
+ attribute_name = (reflection_key.to_s.singularize + '_id').to_sym
100
+ end
101
+
102
+ next if fields.include?(attribute_name)
103
+ attribute attribute_name, type
85
104
  end
86
105
 
87
106
  def internal_resource
data/lib/wings/setup.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  ActiveFedora::Base.include Wings::Valkyrizable
4
4
  ActiveFedora::File.include Wings::Valkyrizable
5
+ Hydra::AccessControl.include Wings::Valkyrizable
5
6
 
6
7
  module ActiveTriples
7
8
  class NodeConfig
@@ -76,6 +77,7 @@ Valkyrie.config.storage_adapter = :active_fedora
76
77
  # A refactor is needed to add the default implementations to hyrax.rb and only handle the wings specific overrides here.
77
78
  custom_queries = [Hyrax::CustomQueries::Navigators::CollectionMembers,
78
79
  Hyrax::CustomQueries::Navigators::ChildCollectionsNavigator,
80
+ Hyrax::CustomQueries::Navigators::ParentCollectionsNavigator,
79
81
  Hyrax::CustomQueries::Navigators::ChildFilesetsNavigator,
80
82
  Hyrax::CustomQueries::Navigators::ChildWorksNavigator,
81
83
  Hyrax::CustomQueries::Navigators::FindFiles,
@@ -41,9 +41,10 @@ module Wings
41
41
  # @param [Valkyrie::Resource] resource
42
42
  # @return [Valkyrie::Resource] the persisted/updated resource
43
43
  def save_all(resources:)
44
- resources.map do |resource|
45
- save(resource: resource)
46
- end
44
+ resources.map { |resource| save(resource: resource) }
45
+ rescue ::Valkyrie::Persistence::StaleObjectError => _err
46
+ raise(::Valkyrie::Persistence::StaleObjectError,
47
+ "One or more resources have been updated by another process.")
47
48
  end
48
49
 
49
50
  # Deletes a resource persisted using ActiveFedora
@@ -51,8 +52,9 @@ module Wings
51
52
  # @return [Valkyrie::Resource] the deleted resource
52
53
  def delete(resource:)
53
54
  af_object = ActiveFedora::Base.new
54
- af_object.id = resource.alternate_ids.first.to_s
55
+ af_object.id = resource.id
55
56
  af_object.delete
57
+ resource
56
58
  end
57
59
 
58
60
  # Deletes all resources from Fedora and Solr
@@ -83,7 +85,8 @@ module Wings
83
85
  etag_lock_token_valid?(af_object: af_object, resource: resource) &&
84
86
  last_modified_lock_token_valid?(af_object: af_object, resource: resource)
85
87
 
86
- raise(::Valkyrie::Persistence::StaleObjectError, resource.id.to_s)
88
+ raise(::Valkyrie::Persistence::StaleObjectError,
89
+ "The object #{resource.id} has been updated by another process.")
87
90
  end
88
91
 
89
92
  ##
@@ -2,16 +2,32 @@
2
2
 
3
3
  module Wings
4
4
  module Valkyrie
5
+ ##
6
+ # @note does not support duplicates!
5
7
  class QueryService
6
8
  attr_reader :adapter
7
9
  extend Forwardable
8
10
  def_delegator :adapter, :resource_factory
9
11
 
10
- # @param adapter [Wings::Valkyrie::MetadataAdapter] The adapter which holds the resource_factory for this query_service.
12
+ ##
13
+ # @param adapter [Wings::Valkyrie::MetadataAdapter] The adapter which
14
+ # holds the resource_factory for this query_service.
11
15
  def initialize(adapter:)
12
16
  @adapter = adapter
13
17
  end
14
18
 
19
+ ##
20
+ # @param :model [Class]
21
+ #
22
+ # @return [Integer]
23
+ def count_all_of_model(model:)
24
+ ActiveFedora::Base
25
+ .where(has_model_ssim: [model_class_for(model).to_rdf_representation,
26
+ model.new.internal_resource.to_s])
27
+ .count
28
+ end
29
+
30
+ ##
15
31
  # WARNING: In general, prefer find_by_alternate_identifier over this
16
32
  # method.
17
33
  #
@@ -23,14 +39,17 @@ module Wings
23
39
  # start getting ObjectNotFoundErrors instead of the objects you wanted
24
40
  #
25
41
  # Find a record using a Valkyrie ID, and map it to a Valkyrie Resource
42
+ #
26
43
  # @param [Valkyrie::ID, String] id
27
44
  # @return [Valkyrie::Resource]
28
- # @raise [Hyrax::ObjectNotFoundError]
45
+ # @raise [Valkyrie::Persistence::ObjectNotFoundError]
29
46
  def find_by(id:)
30
47
  find_by_alternate_identifier(alternate_identifier: id)
31
48
  end
32
49
 
50
+ ##
33
51
  # Find all work/collection records, and map to Valkyrie Resources
52
+ #
34
53
  # @return [Array<Valkyrie::Resource>]
35
54
  def find_all
36
55
  ::ActiveFedora::Base.all.map do |obj|
@@ -38,7 +57,10 @@ module Wings
38
57
  end
39
58
  end
40
59
 
41
- # Find all work/collection records of a given model, and map to Valkyrie Resources
60
+ ##
61
+ # Find all work/collection records of a given model, and map to Valkyrie
62
+ # Resources
63
+ #
42
64
  # @param model [Class]
43
65
  # @return [Array<Valkyrie::Resource>]
44
66
  def find_all_of_model(model:)
@@ -47,69 +69,89 @@ module Wings
47
69
  end
48
70
  end
49
71
 
50
- # Find an array of record using Valkyrie IDs, and map them to Valkyrie Resources maintaining order based on given ids
72
+ ##
73
+ # Find an array of record using Valkyrie IDs, and map them to Valkyrie
74
+ # Resources maintaining order based on given ids
75
+ #
76
+ # @note ignores non-existent ids.
77
+ #
51
78
  # @param [Array<Valkyrie::ID, String>] ids
79
+ #
52
80
  # @return [Array<Valkyrie::Resource>]
53
- # NOTE: Ignores non-existent ids.
81
+ # @raise [ArgumentError]
54
82
  def find_many_by_ids(ids:)
55
- ids.each do |id|
56
- id = ::Valkyrie::ID.new(id.to_s) if id.is_a?(String)
57
- validate_id(id)
58
- end
59
- resources = []
60
- ids.uniq.map(&:to_s).each do |id|
83
+ ids.all? { |i| i.respond_to?(:to_str) } ||
84
+ raise(ArgumentError, 'id must be a Valkyrie::ID')
85
+
86
+ return enum_for(:find_many_by_ids, ids: ids) unless block_given?
87
+
88
+ ids.map(&:to_s).uniq.each do |id|
61
89
  begin
62
90
  af_object = ActiveFedora::Base.find(id)
63
- resources << resource_factory.to_resource(object: af_object)
91
+ yield resource_factory.to_resource(object: af_object)
64
92
  rescue ::ActiveFedora::ObjectNotFoundError, Ldp::Gone
65
93
  next
66
94
  end
67
95
  end
68
- resources
69
96
  end
70
97
 
98
+ ##
71
99
  # Find a record using an alternate ID, and map it to a Valkyrie Resource
100
+ #
72
101
  # @param [Valkyrie::ID, String] id
73
102
  # @param [boolean] optionally return ActiveFedora object/errors
103
+ #
74
104
  # @return [Valkyrie::Resource]
75
- # @raise [Hyrax::ObjectNotFoundError]
105
+ # @raise [Valkyrie::Persistence::ObjectNotFoundError]
76
106
  def find_by_alternate_identifier(alternate_identifier:, use_valkyrie: true)
77
- alternate_identifier = ::Valkyrie::ID.new(alternate_identifier.to_s) if alternate_identifier.is_a?(String)
78
- validate_id(alternate_identifier)
79
- object = ::ActiveFedora::Base.find(alternate_identifier.to_s)
80
- return object if use_valkyrie == false
81
- resource_factory.to_resource(object: object)
82
- rescue ActiveFedora::ObjectNotFoundError, Ldp::Gone
83
- raise Hyrax::ObjectNotFoundError
107
+ raise(ArgumentError, 'id must be a Valkyrie::ID') unless
108
+ alternate_identifier.respond_to?(:to_str)
109
+
110
+ af_object = ActiveFedora::Base.find(alternate_identifier.to_s)
111
+
112
+ use_valkyrie ? resource_factory.to_resource(object: af_object) : af_object
113
+ rescue ActiveFedora::ObjectNotFoundError, Ldp::Gone => err
114
+ raise err unless use_valkyrie
115
+ raise ::Valkyrie::Persistence::ObjectNotFoundError
84
116
  end
85
117
 
118
+ ##
86
119
  # Find all members of a given resource, and map to Valkyrie Resources
120
+ #
87
121
  # @param resource [Valkyrie::Resource]
88
122
  # @param model [Class]
123
+ #
89
124
  # @return [Array<Valkyrie::Resource>]
90
125
  def find_members(resource:, model: nil)
91
- return [] unless resource.respond_to?(:member_ids) && resource.member_ids.present?
92
- all_members = find_many_by_ids(ids: resource.member_ids)
93
- return all_members unless model
126
+ return [] if resource.try(:member_ids).blank?
127
+ return find_many_by_ids(ids: resource.member_ids) unless model
128
+
94
129
  find_model = model_class_for(model)
95
- all_members.select { |member_resource| model_class_for(member_resource.class) == find_model }
130
+ find_many_by_ids(ids: resource.member_ids)
131
+ .select { |member_resource| model_class_for(member_resource.class) == find_model }
96
132
  end
97
133
 
134
+ ##
98
135
  # Find the Valkyrie Resources referenced by another Valkyrie Resource
136
+ #
99
137
  # @param resource [<Valkyrie::Resource>]
100
138
  # @param property [Symbol] the property holding the references to another resource
101
139
  # @return [Array<Valkyrie::Resource>]
102
- def find_references_by(resource:, property:)
103
- object = resource_factory.from_resource(resource: resource)
104
- object.send(property).map do |reference|
105
- af_id = find_id_for(reference)
106
- resource_factory.to_resource(object: ::ActiveFedora::Base.find(af_id))
140
+ def find_references_by(resource:, property:, model: nil)
141
+ return find_many_by_ids(ids: Array(resource.send(property))) unless model
142
+
143
+ results = resource.public_send(property).map do |reference|
144
+ resource_factory.to_resource(object: ::ActiveFedora::Base.find(reference))
107
145
  end
146
+
147
+ results.select { |r| r.class.name == model.name }
108
148
  rescue ActiveFedora::ObjectNotFoundError
109
149
  []
110
150
  end
111
151
 
152
+ ##
112
153
  # Get all resources which link to a resource or id with a given property.
154
+ #
113
155
  # @param resource [Valkyrie::Resource] The resource which is being referenced by
114
156
  # other resources.
115
157
  # @param resource [Valkyrie::ID] The id of the resource which is being referenced by
@@ -121,30 +163,37 @@ module Wings
121
163
  # @return [Array<Valkyrie::Resource>] All resources in the persistence backend
122
164
  # which have the ID of the given `resource` in their `property` property. Not
123
165
  # in order.
124
- def find_inverse_references_by(resource: nil, id: nil, property:)
166
+ def find_inverse_references_by(resource: nil, id: nil, model: nil, property:)
125
167
  raise ArgumentError, "Provide resource or id" unless resource || id
126
- id ||= resource.alternate_ids.first
168
+ id ||= resource.id
127
169
  raise ArgumentError, "Resource has no id; is it persisted?" unless id
128
- uri = Hyrax::Base.id_to_uri(id.to_s)
129
- ActiveFedora::Base.where("+(#{property}_ssim: \"#{uri}\" OR #{property}_ssim: \"#{id}\")").map do |obj|
170
+
171
+ active_fedora_model = model ? model_class_for(model) : ActiveFedora::Base
172
+
173
+ uri = active_fedora_model.id_to_uri(id.to_s)
174
+ active_fedora_model.where("+(#{property}_ssim: \"#{uri}\" OR #{property}_ssim: \"#{id}\")").map do |obj|
130
175
  resource_factory.to_resource(object: obj)
131
176
  end
132
177
  end
133
178
 
179
+ ##
134
180
  # Find all parents of a given resource.
181
+ #
135
182
  # @param resource [Valkyrie::Resource] The resource whose parents are being searched
136
183
  # for.
137
184
  # @return [Array<Valkyrie::Resource>] All resources which are parents of the given
138
185
  # `resource`. This means the resource's `id` appears in their `member_ids`
139
186
  # array.
140
187
  def find_parents(resource:)
141
- id = resource.alternate_ids.first
142
- ActiveFedora::Base.where("member_ids_ssim: \"#{id}\"").map do |obj|
188
+ ActiveFedora::Base.where("member_ids_ssim: \"#{resource.id}\"").map do |obj|
143
189
  resource_factory.to_resource(object: obj)
144
190
  end
145
191
  end
146
192
 
147
- # Constructs a Valkyrie::Persistence::CustomQueryContainer using this query service
193
+ ##
194
+ # Constructs a Valkyrie::Persistence::CustomQueryContainer using this
195
+ # query service
196
+ #
148
197
  # @return [Valkyrie::Persistence::CustomQueryContainer]
149
198
  def custom_queries
150
199
  @custom_queries ||= ::Valkyrie::Persistence::CustomQueryContainer.new(query_service: self)
@@ -152,7 +201,9 @@ module Wings
152
201
 
153
202
  private
154
203
 
204
+ ##
155
205
  # Determines whether or not an Object is a Valkyrie ID
206
+ #
156
207
  # @param [Object] id
157
208
  # @raise [ArgumentError]
158
209
  def validate_id(id)
@@ -160,10 +211,14 @@ module Wings
160
211
  end
161
212
 
162
213
  def find_id_for(reference)
163
- return ::Hyrax::Base.uri_to_id(reference.id) if reference.class == ActiveTriples::Resource
164
- return reference if reference.class == String
165
- # not a supported type
166
- ''
214
+ case reference
215
+ when ActiveTriples::Resource
216
+ ::Hyrax::Base.uri_to_id(reference.id)
217
+ when String
218
+ reference
219
+ else # not a supported type
220
+ ''
221
+ end
167
222
  end
168
223
 
169
224
  def model_class_for(model)