bulkrax 7.0.0 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/bulkrax/datatables.js +1 -1
  3. data/app/controllers/bulkrax/exporters_controller.rb +1 -1
  4. data/app/controllers/bulkrax/importers_controller.rb +2 -1
  5. data/app/controllers/concerns/bulkrax/datatables_behavior.rb +15 -15
  6. data/app/factories/bulkrax/object_factory.rb +135 -163
  7. data/app/factories/bulkrax/object_factory_interface.rb +491 -0
  8. data/app/factories/bulkrax/valkyrie_object_factory.rb +402 -0
  9. data/app/helpers/bulkrax/importers_helper.rb +1 -1
  10. data/app/helpers/bulkrax/validation_helper.rb +4 -4
  11. data/app/jobs/bulkrax/create_relationships_job.rb +27 -16
  12. data/app/jobs/bulkrax/delete_job.rb +3 -2
  13. data/app/jobs/bulkrax/download_cloud_file_job.rb +16 -3
  14. data/app/jobs/bulkrax/import_file_set_job.rb +5 -2
  15. data/app/jobs/bulkrax/importer_job.rb +18 -2
  16. data/app/matchers/bulkrax/application_matcher.rb +0 -2
  17. data/app/models/bulkrax/csv_collection_entry.rb +1 -1
  18. data/app/models/bulkrax/csv_entry.rb +7 -6
  19. data/app/models/bulkrax/entry.rb +7 -11
  20. data/app/models/bulkrax/exporter.rb +2 -2
  21. data/app/models/bulkrax/importer.rb +1 -3
  22. data/app/models/bulkrax/oai_entry.rb +0 -3
  23. data/app/models/bulkrax/oai_set_entry.rb +1 -1
  24. data/app/models/bulkrax/rdf_collection_entry.rb +1 -1
  25. data/app/models/bulkrax/rdf_entry.rb +70 -69
  26. data/app/models/bulkrax/xml_entry.rb +0 -1
  27. data/app/models/concerns/bulkrax/dynamic_record_lookup.rb +2 -19
  28. data/app/models/concerns/bulkrax/export_behavior.rb +2 -2
  29. data/app/models/concerns/bulkrax/file_factory.rb +174 -118
  30. data/app/models/concerns/bulkrax/file_set_entry_behavior.rb +2 -2
  31. data/app/models/concerns/bulkrax/has_matchers.rb +28 -25
  32. data/app/models/concerns/bulkrax/import_behavior.rb +10 -17
  33. data/app/models/concerns/bulkrax/importer_exporter_behavior.rb +3 -2
  34. data/app/parsers/bulkrax/application_parser.rb +31 -7
  35. data/app/parsers/bulkrax/bagit_parser.rb +175 -174
  36. data/app/parsers/bulkrax/csv_parser.rb +15 -5
  37. data/app/parsers/bulkrax/oai_dc_parser.rb +18 -0
  38. data/app/parsers/bulkrax/parser_export_record_set.rb +18 -22
  39. data/app/parsers/bulkrax/xml_parser.rb +0 -2
  40. data/app/services/bulkrax/factory_class_finder.rb +2 -0
  41. data/app/services/bulkrax/remove_relationships_for_importer.rb +3 -1
  42. data/app/services/hyrax/custom_queries/find_by_source_identifier.rb +50 -0
  43. data/app/services/wings/custom_queries/find_by_source_identifier.rb +32 -0
  44. data/app/views/bulkrax/entries/_parsed_metadata.html.erb +2 -2
  45. data/app/views/bulkrax/entries/_raw_metadata.html.erb +2 -2
  46. data/app/views/bulkrax/entries/show.html.erb +9 -8
  47. data/app/views/bulkrax/exporters/edit.html.erb +1 -1
  48. data/app/views/bulkrax/exporters/new.html.erb +1 -1
  49. data/app/views/bulkrax/exporters/show.html.erb +4 -2
  50. data/app/views/bulkrax/importers/_browse_everything.html.erb +2 -2
  51. data/app/views/bulkrax/importers/_csv_fields.html.erb +1 -1
  52. data/app/views/bulkrax/importers/edit.html.erb +1 -1
  53. data/app/views/bulkrax/importers/new.html.erb +1 -1
  54. data/app/views/bulkrax/importers/show.html.erb +1 -1
  55. data/app/views/bulkrax/importers/upload_corrected_entries.html.erb +2 -2
  56. data/app/views/bulkrax/shared/_bulkrax_errors.html.erb +1 -1
  57. data/app/views/bulkrax/shared/_bulkrax_field_mapping.html.erb +1 -1
  58. data/config/locales/bulkrax.en.yml +7 -0
  59. data/db/migrate/20230608153601_add_indices_to_bulkrax.rb +20 -9
  60. data/db/migrate/20240307053156_add_index_to_metadata_bulkrax_identifier.rb +18 -0
  61. data/lib/bulkrax/engine.rb +23 -6
  62. data/lib/bulkrax/version.rb +1 -1
  63. data/lib/bulkrax.rb +54 -52
  64. data/lib/generators/bulkrax/templates/config/initializers/bulkrax.rb +2 -0
  65. data/lib/tasks/bulkrax_tasks.rake +1 -0
  66. data/lib/tasks/reset.rake +4 -4
  67. metadata +24 -8
  68. data/lib/bulkrax/persistence_layer/active_fedora_adapter.rb +0 -27
  69. data/lib/bulkrax/persistence_layer/valkyrie_adapter.rb +0 -8
  70. data/lib/bulkrax/persistence_layer.rb +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae65205e27f8cff17680fb48e361dd9ed1740decda56dcded099a44413c4ae89
4
- data.tar.gz: c4db878ab4205b3b6bbbb82f251ea3947ea5390dfaf1fe4138d2fc82f3cb0c6b
3
+ metadata.gz: 6ca767b1e461d5830774bb4d7c49eade799d14298625bdbdccdcbdc0ac997f88
4
+ data.tar.gz: b5024ea772132123fcb922fbe183d22950428ea50b7a8b4152c6bd781b94510f
5
5
  SHA512:
6
- metadata.gz: 4ee86776f2716cd07747e93ba4e3f8d48a8427c10595d14a0a24a321a9a28de8729494bdbb48b4f4b40db4ff102dc184401ab869135cbb36032dbf5f55f623f5
7
- data.tar.gz: 5daf4da40338fc769052052106fc051746967a4c8ecabc89219daddb87a676e2500a1c42906aa55a14bbbcf6749868b1d41dff5388dad636b4d806da7f62bb6d
6
+ metadata.gz: 91004f88a97054107a3bbbcbe7f3b3dd84226a286df47992c13bfc5fb483c3bfd4aaa9190e08e567258e5105a317a37bba58fa7857ee6c534153ba930b608ad7
7
+ data.tar.gz: 89a32c155c3931e486b2d41215942b291eb724c59833a031fdc4815a72d26a2df13b015c1b1e2c0dafd608e58ec481a574e20da7bcf95ed76b3e45c3d5f19287
@@ -133,7 +133,7 @@ function refreshLink() {
133
133
  refreshLink.onclick = function() {
134
134
  this.api().ajax.reload(null, false)
135
135
  }.bind(this)
136
- refreshLink.classList.value = 'glyphicon glyphicon-refresh'
136
+ refreshLink.classList.value = 'fa fa-refresh'
137
137
  refreshLink.style.marginLeft = '10px'
138
138
  document.querySelector('div.dataTables_filter').firstChild.append(refreshLink)
139
139
  }
@@ -60,7 +60,7 @@ module Bulkrax
60
60
  end
61
61
 
62
62
  # Correctly populate export_source_collection input
63
- @collection = Collection.find(@exporter.export_source) if @exporter.export_source.present? && @exporter.export_from == 'collection'
63
+ @collection = Bulkrax.object_factory.find(@exporter.export_source) if @exporter.export_source.present? && @exporter.export_from == 'collection'
64
64
  end
65
65
 
66
66
  # POST /exporters
@@ -214,10 +214,11 @@ module Bulkrax
214
214
  return if file.blank? && cloud_files.blank?
215
215
  @importer[:parser_fields]['import_file_path'] = @importer.parser.write_import_file(file) if file.present?
216
216
  if cloud_files.present?
217
+ @importer[:parser_fields]['cloud_file_paths'] = cloud_files
217
218
  # For BagIt, there will only be one bag, so we get the file_path back and set import_file_path
218
219
  # For CSV, we expect only file uploads, so we won't get the file_path back
219
220
  # and we expect the import_file_path to be set already
220
- target = @importer.parser.retrieve_cloud_files(cloud_files)
221
+ target = @importer.parser.retrieve_cloud_files(cloud_files, @importer)
221
222
  @importer[:parser_fields]['import_file_path'] = target if target.present?
222
223
  end
223
224
  @importer.save
@@ -103,7 +103,7 @@ module Bulkrax
103
103
  {
104
104
  data: result,
105
105
  recordsTotal: Bulkrax::Importer.count,
106
- recordsFiltered: importers.size
106
+ recordsFiltered: Bulkrax::Importer.count
107
107
  }
108
108
  end
109
109
 
@@ -120,7 +120,7 @@ module Bulkrax
120
120
  {
121
121
  data: result,
122
122
  recordsTotal: Bulkrax::Exporter.count,
123
- recordsFiltered: exporters.size
123
+ recordsFiltered: Bulkrax::Exporter.count
124
124
  }
125
125
  end
126
126
 
@@ -145,37 +145,37 @@ module Bulkrax
145
145
 
146
146
  def entry_util_links(e, item)
147
147
  links = []
148
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-info-sign"></span>'), view_context.item_entry_path(item, e))
149
- links << "<a class='glyphicon glyphicon-repeat' data-toggle='modal' data-target='#bulkraxItemModal' data-entry-id='#{e.id}'></a>" if view_context.an_importer?(item)
150
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-trash"></span>'), view_context.item_entry_path(item, e), method: :delete, data: { confirm: 'This will delete the entry and any work associated with it. Are you sure?' })
148
+ links << view_context.link_to(view_context.raw('<span class="fa fa-info-circle"></span>'), view_context.item_entry_path(item, e))
149
+ links << "<a class='fa fa-repeat' data-toggle='modal' data-target='#bulkraxItemModal' data-entry-id='#{e.id}'></a>" if view_context.an_importer?(item)
150
+ links << view_context.link_to(view_context.raw('<span class="fa fa-trash"></span>'), view_context.item_entry_path(item, e), method: :delete, data: { confirm: 'This will delete the entry and any work associated with it. Are you sure?' })
151
151
  links.join(" ")
152
152
  end
153
153
 
154
154
  def status_message_for(e)
155
155
  if e.status_message == "Complete"
156
- "<td><span class='glyphicon glyphicon-ok' style='color: green;'></span> #{e.status_message}</td>"
156
+ "<td><span class='fa fa-check' style='color: green;'></span> #{e.status_message}</td>"
157
157
  elsif e.status_message == "Pending"
158
- "<td><span class='glyphicon glyphicon-option-horizontal' style='color: blue;'></span> #{e.status_message}</td>"
158
+ "<td><span class='fa fa-ellipsis-h' style='color: blue;'></span> #{e.status_message}</td>"
159
159
  elsif e.status_message == "Skipped"
160
- "<td><span class='glyphicon glyphicon-step-forward' style='color: yellow;'></span> #{e.status_message}</td>"
160
+ "<td><span class='fa fa-step-forward' style='color: yellow;'></span> #{e.status_message}</td>"
161
161
  else
162
- "<td><span class='glyphicon glyphicon-remove' style='color: #{e.status == 'Deleted' ? 'green' : 'red'};'></span> #{e.status_message}</td>"
162
+ "<td><span class='fa fa-remove' style='color: #{e.status == 'Deleted' ? 'green' : 'red'};'></span> #{e.status_message}</td>"
163
163
  end
164
164
  end
165
165
 
166
166
  def importer_util_links(i)
167
167
  links = []
168
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-info-sign"></span>'), importer_path(i))
169
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-pencil"></span>'), edit_importer_path(i))
170
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-remove"></span>'), i, method: :delete, data: { confirm: 'Are you sure?' })
168
+ links << view_context.link_to(view_context.raw('<span class="fa fa-info-circle"></span>'), importer_path(i))
169
+ links << view_context.link_to(view_context.raw('<span class="fa fa-pencil"></span>'), edit_importer_path(i))
170
+ links << view_context.link_to(view_context.raw('<span class="fa fa-remove"></span>'), i, method: :delete, data: { confirm: 'Are you sure?' })
171
171
  links.join(" ")
172
172
  end
173
173
 
174
174
  def exporter_util_links(i)
175
175
  links = []
176
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-info-sign"></span>'), exporter_path(i))
177
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-pencil"></span>'), edit_exporter_path(i), data: { turbolinks: false })
178
- links << view_context.link_to(view_context.raw('<span class="glyphicon glyphicon-remove"></span>'), i, method: :delete, data: { confirm: 'Are you sure?' })
176
+ links << view_context.link_to(view_context.raw('<span class="fa fa-info-circle"></span>'), exporter_path(i))
177
+ links << view_context.link_to(view_context.raw('<span class="fa fa-pencil"></span>'), edit_exporter_path(i), data: { turbolinks: false })
178
+ links << view_context.link_to(view_context.raw('<span class="fa fa-remove"></span>'), i, method: :delete, data: { confirm: 'Are you sure?' })
179
179
  links.join(" ")
180
180
  end
181
181
 
@@ -1,153 +1,171 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bulkrax
4
- class ObjectFactory # rubocop:disable Metrics/ClassLength
5
- extend ActiveModel::Callbacks
4
+ # rubocop:disable Metrics/ClassLength
5
+ class ObjectFactory < ObjectFactoryInterface
6
6
  include Bulkrax::FileFactory
7
- include DynamicRecordLookup
8
7
 
9
- # @api private
10
- #
11
- # These are the attributes that we assume all "work type" classes (e.g. the given :klass) will
12
- # have in addition to their specific attributes.
13
- #
14
- # @return [Array<Symbol>]
15
- # @see #permitted_attributes
16
- class_attribute :base_permitted_attributes,
17
- default: %i[id edit_users edit_groups read_groups visibility work_members_attributes admin_set_id]
8
+ ##
9
+ # @!group Class Method Interface
18
10
 
19
- # @return [Boolean]
20
- #
21
- # @example
22
- # Bulkrax::ObjectFactory.transformation_removes_blank_hash_values = true
23
- #
24
- # @see #transform_attributes
25
- # @see https://github.com/samvera-labs/bulkrax/pull/708 For discussion concerning this feature
26
- # @see https://github.com/samvera-labs/bulkrax/wiki/Interacting-with-Metadata For documentation
27
- # concerning default behavior.
28
- class_attribute :transformation_removes_blank_hash_values, default: false
11
+ ##
12
+ # @note This does not save either object. We need to do that in another
13
+ # loop. Why? Because we might be adding many items to the parent.
14
+ def self.add_child_to_parent_work(parent:, child:)
15
+ return true if parent.ordered_members.to_a.include?(child_record)
29
16
 
30
- define_model_callbacks :save, :create
31
- attr_reader :attributes, :object, :source_identifier_value, :klass, :replace_files, :update_files, :work_identifier, :work_identifier_search_field, :related_parents_parsed_mapping, :importer_run_id
17
+ parent.ordered_members << child
18
+ end
32
19
 
33
- # rubocop:disable Metrics/ParameterLists
34
- def initialize(attributes:, source_identifier_value:, work_identifier:, work_identifier_search_field:, related_parents_parsed_mapping: nil, replace_files: false, user: nil, klass: nil, importer_run_id: nil, update_files: false)
35
- @attributes = ActiveSupport::HashWithIndifferentAccess.new(attributes)
36
- @replace_files = replace_files
37
- @update_files = update_files
38
- @user = user || User.batch_user
39
- @work_identifier = work_identifier
40
- @work_identifier_search_field = work_identifier_search_field
41
- @related_parents_parsed_mapping = related_parents_parsed_mapping
42
- @source_identifier_value = source_identifier_value
43
- @klass = klass || Bulkrax.default_work_type.constantize
44
- @importer_run_id = importer_run_id
20
+ def self.add_resource_to_collection(collection:, resource:, user:)
21
+ collection.try(:reindex_extent=, Hyrax::Adapters::NestingIndexAdapter::LIMITED_REINDEX) if
22
+ defined?(Hyrax::Adapters::NestingIndexAdapter)
23
+ resource.member_of_collections << collection
24
+ save!(resource: resource, user: user)
45
25
  end
46
- # rubocop:enable Metrics/ParameterLists
47
26
 
48
- # update files is set, replace files is set or this is a create
49
- def with_files
50
- update_files || replace_files || !object
27
+ def self.update_index_for_file_sets_of(resource:)
28
+ resource.file_sets.each(&:update_index) if resource.respond_to?(:file_sets)
51
29
  end
52
30
 
53
- def run
54
- arg_hash = { id: attributes[:id], name: 'UPDATE', klass: klass }
55
- @object = find
56
- if object
57
- object.reindex_extent = Hyrax::Adapters::NestingIndexAdapter::LIMITED_REINDEX if object.respond_to?(:reindex_extent)
58
- ActiveSupport::Notifications.instrument('import.importer', arg_hash) { update }
59
- else
60
- ActiveSupport::Notifications.instrument('import.importer', arg_hash.merge(name: 'CREATE')) { create }
61
- end
62
- yield(object) if block_given?
63
- object
31
+ ##
32
+ # @see Bulkrax::ObjectFactoryInterface
33
+ def self.export_properties
34
+ # TODO: Consider how this may or may not work for Valkyrie
35
+ properties = Bulkrax.curation_concerns.map { |work| work.properties.keys }.flatten.uniq.sort
36
+ properties.reject { |prop| Bulkrax.reserved_properties.include?(prop) }
64
37
  end
65
38
 
66
- def run!
67
- self.run
68
- # Create the error exception if the object is not validly saved for some reason
69
- raise ActiveFedora::RecordInvalid, object if !object.persisted? || object.changed?
70
- object
39
+ def self.field_multi_value?(field:, model:)
40
+ return false unless field_supported?(field: field, model: model)
41
+ return false unless model.singleton_methods.include?(:properties)
42
+
43
+ model&.properties&.[](field)&.[]("multiple")
71
44
  end
72
45
 
73
- def update
74
- raise "Object doesn't exist" unless object
75
- destroy_existing_files if @replace_files && ![Collection, FileSet].include?(klass)
76
- attrs = transform_attributes(update: true)
77
- run_callbacks :save do
78
- if klass == Collection
79
- update_collection(attrs)
80
- elsif klass == FileSet
81
- update_file_set(attrs)
82
- else
83
- update_work(attrs)
84
- end
85
- end
86
- object.apply_depositor_metadata(@user) && object.save! if object.depositor.nil?
87
- log_updated(object)
46
+ def self.field_supported?(field:, model:)
47
+ model.method_defined?(field) && model.properties[field].present?
48
+ end
49
+
50
+ def self.file_sets_for(resource:)
51
+ return [] if resource.blank?
52
+ return [resource] if resource.is_a?(Bulkrax.file_model_class)
53
+
54
+ resource.file_sets
88
55
  end
89
56
 
90
- def find
91
- found = find_by_id if attributes[:id].present?
92
- return found if found.present?
93
- return search_by_identifier if attributes[work_identifier].present?
57
+ ##
58
+ #
59
+ # @see Bulkrax::ObjectFactoryInterface
60
+ def self.find(id)
61
+ ActiveFedora::Base.find(id)
62
+ rescue ActiveFedora::ObjectNotFoundError => e
63
+ raise ObjectFactoryInterface::ObjectNotFoundError, e.message
94
64
  end
95
65
 
96
- def find_by_id
97
- klass.find(attributes[:id]) if klass.exists?(attributes[:id])
66
+ def self.find_or_create_default_admin_set
67
+ # NOTE: Hyrax 5+ removed this method
68
+ AdminSet.find_or_create_default_admin_set_id
98
69
  end
99
70
 
100
- def find_or_create
101
- o = find
102
- return o if o
103
- run(&:save!)
71
+ def self.publish(**)
72
+ return true
104
73
  end
105
74
 
106
- def search_by_identifier
107
- query = { work_identifier_search_field =>
108
- source_identifier_value }
109
- # Query can return partial matches (something6 matches both something6 and something68)
110
- # so we need to weed out any that are not the correct full match. But other items might be
111
- # in the multivalued field, so we have to go through them one at a time.
112
- match = klass.where(query).detect { |m| m.send(work_identifier).include?(source_identifier_value) }
75
+ ##
76
+ # @param value [String]
77
+ # @param klass [Class, #where]
78
+ # @param field [String, Symbol] A convenience parameter where we pass the
79
+ # same value to search_field and name_field.
80
+ # @param search_field [String, Symbol] the Solr field name
81
+ # (e.g. "title_tesim")
82
+ # @param name_field [String] the ActiveFedora::Base property name
83
+ # (e.g. "title")
84
+ # @param verify_property [TrueClass] when true, verify that the given :klass
85
+ #
86
+ # @return [NilClass] when no object is found.
87
+ # @return [ActiveFedora::Base] when a match is found, an instance of given
88
+ # :klass
89
+ # rubocop:disable Metrics/ParameterLists
90
+ #
91
+ # @note HEY WE'RE USING THIS FOR A WINGS CUSTOM QUERY. BE CAREFUL WITH
92
+ # REMOVING IT.
93
+ #
94
+ # @see # {Wings::CustomQueries::FindBySourceIdentifier#find_by_model_and_property_value}
95
+ def self.search_by_property(value:, klass:, field: nil, search_field: nil, name_field: nil, verify_property: false)
96
+ return nil unless klass.respond_to?(:where)
97
+ # We're not going to try to match nil nor "".
98
+ return if value.blank?
99
+ return if verify_property && !klass.properties.keys.include?(search_field)
100
+
101
+ search_field ||= field
102
+ name_field ||= field
103
+ raise "You must provide either (search_field AND name_field) OR field parameters" if search_field.nil? || name_field.nil?
104
+ # NOTE: Query can return partial matches (something6 matches both
105
+ # something6 and something68) so we need to weed out any that are not the
106
+ # correct full match. But other items might be in the multivalued field,
107
+ # so we have to go through them one at a time.
108
+ #
109
+ # A ssi field is string, so we're looking at exact matches.
110
+ # A tesi field is text, so partial matches work.
111
+ #
112
+ # We need to wrap the result in an Array, else we might have a scalar that
113
+ # will result again in partial matches.
114
+ match = klass.where(search_field => value).detect do |m|
115
+ # Don't use Array.wrap as we likely have an ActiveTriples::Relation
116
+ # which defiantly claims to be an Array yet does not behave consistently
117
+ # with an Array. Hopefully the name_field is not a Date or Time object,
118
+ # Because that too will be a mess.
119
+ Array(m.send(name_field)).include?(value)
120
+ end
113
121
  return match if match
114
122
  end
123
+ # rubocop:enable Metrics/ParameterLists
124
+
125
+ def self.query(q, **kwargs)
126
+ ActiveFedora::SolrService.query(q, **kwargs)
127
+ end
115
128
 
116
- # An ActiveFedora bug when there are many habtm <-> has_many associations means they won't all get saved.
117
- # https://github.com/projecthydra/active_fedora/issues/874
118
- # 2+ years later, still open!
119
- def create
120
- attrs = transform_attributes
121
- @object = klass.new
122
- object.reindex_extent = Hyrax::Adapters::NestingIndexAdapter::LIMITED_REINDEX if defined?(Hyrax::Adapters::NestingIndexAdapter) && object.respond_to?(:reindex_extent)
123
- run_callbacks :save do
124
- run_callbacks :create do
125
- if klass == Collection
126
- create_collection(attrs)
127
- elsif klass == FileSet
128
- create_file_set(attrs)
129
- else
130
- create_work(attrs)
131
- end
132
- end
129
+ def self.clean!
130
+ super do
131
+ ActiveFedora::Cleaner.clean!
133
132
  end
134
- object.apply_depositor_metadata(@user) && object.save! if object.depositor.nil?
135
- log_created(object)
136
133
  end
137
134
 
138
- def log_created(obj)
139
- msg = "Created #{klass.model_name.human} #{obj.id}"
140
- Rails.logger.info("#{msg} (#{Array(attributes[work_identifier]).first})")
135
+ def self.solr_name(field_name)
136
+ if defined?(Hyrax)
137
+ Hyrax.index_field_mapper.solr_name(field_name)
138
+ else
139
+ ActiveFedora.index_field_mapper.solr_name(field_name)
140
+ end
141
+ end
142
+
143
+ def self.ordered_file_sets_for(object)
144
+ object&.ordered_members.to_a.select(&:file_set?)
145
+ end
146
+
147
+ def self.save!(resource:, **)
148
+ resource.save!
141
149
  end
142
150
 
143
- def log_updated(obj)
144
- msg = "Updated #{klass.model_name.human} #{obj.id}"
145
- Rails.logger.info("#{msg} (#{Array(attributes[work_identifier]).first})")
151
+ def self.update_index(resources: [])
152
+ Array(resources).each(&:update_index)
146
153
  end
154
+ # @!endgroup Class Method Interface
155
+ ##
147
156
 
148
- def log_deleted_fs(obj)
149
- msg = "Deleted All Files from #{obj.id}"
150
- Rails.logger.info("#{msg} (#{Array(attributes[work_identifier]).first})")
157
+ def find_by_id
158
+ return false if attributes[:id].blank?
159
+ # Rails / Ruby upgrade, we moved from :exists? to :exist? However we want to continue (for a
160
+ # bit) to support older versions.
161
+ method_name = klass.respond_to?(:exist?) ? :exist? : :exists?
162
+ klass.find(attributes[:id]) if klass.send(method_name, attributes[:id])
163
+ rescue Valkyrie::Persistence::ObjectNotFoundError
164
+ false
165
+ end
166
+
167
+ def delete(_user)
168
+ find&.delete
151
169
  end
152
170
 
153
171
  private
@@ -238,52 +256,6 @@ module Bulkrax
238
256
  update == true ? actor.update_content(tmp_file) : actor.create_content(tmp_file, from_url: true)
239
257
  tmp_file.close
240
258
  end
241
-
242
- def clean_attrs(attrs)
243
- # avoid the "ArgumentError: Identifier must be a string of size > 0 in order to be treeified" error
244
- # when setting object.attributes
245
- attrs.delete('id') if attrs['id'].blank?
246
- attrs
247
- end
248
-
249
- def collection_type(attrs)
250
- return attrs if attrs['collection_type_gid'].present?
251
-
252
- attrs['collection_type_gid'] = Hyrax::CollectionType.find_or_create_default_collection_type.to_global_id.to_s
253
- attrs
254
- end
255
-
256
- # Override if we need to map the attributes from the parser in
257
- # a way that is compatible with how the factory needs them.
258
- def transform_attributes(update: false)
259
- @transform_attributes = attributes.slice(*permitted_attributes)
260
- @transform_attributes.merge!(file_attributes(update_files)) if with_files
261
- @transform_attributes = remove_blank_hash_values(@transform_attributes) if transformation_removes_blank_hash_values?
262
- update ? @transform_attributes.except(:id) : @transform_attributes
263
- end
264
-
265
- # Regardless of what the Parser gives us, these are the properties we are prepared to accept.
266
- def permitted_attributes
267
- klass.properties.keys.map(&:to_sym) + base_permitted_attributes
268
- end
269
-
270
- # Return a copy of the given attributes, such that all values that are empty or an array of all
271
- # empty values are fully emptied. (See implementation details)
272
- #
273
- # @param attributes [Hash]
274
- # @return [Hash]
275
- #
276
- # @see https://github.com/emory-libraries/dlp-curate/issues/1973
277
- def remove_blank_hash_values(attributes)
278
- dupe = attributes.dup
279
- dupe.each do |key, values|
280
- if values.is_a?(Array) && values.all? { |value| value.is_a?(String) && value.empty? }
281
- dupe[key] = []
282
- elsif values.is_a?(String) && values.empty?
283
- dupe[key] = nil
284
- end
285
- end
286
- dupe
287
- end
288
259
  end
260
+ # rubocop:enable Metrics/ClassLength
289
261
  end