lib/ddr/datastreams/datastream_behavior.rb in ddr-models-2.6.2 vs lib/ddr/datastreams/datastream_behavior.rb in ddr-models-2.7.0.rc1

- old
+ new

@@ -1,19 +1,25 @@ module Ddr module Datastreams module DatastreamBehavior + extend ActiveSupport::Concern DEFAULT_FILE_EXTENSION = "bin" STRFTIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%LZ" + included do + around_save :notify_save + around_destroy :notify_delete + end + def validate_checksum! checksum, checksum_type=nil raise Ddr::Models::Error, "Checksum cannot be validated on new datastream." if new? raise Ddr::Models::Error, "Checksum cannot be validated on unpersisted content." if content_changed? raise Ddr::Models::ChecksumInvalid, "The repository internal checksum validation failed." unless dsChecksumValid algorithm = checksum_type || self.checksumType - ds_checksum = if algorithm == self.checksumType + ds_checksum = if !external? && algorithm == self.checksumType self.checksum else content_digest(algorithm) end if checksum == ds_checksum @@ -21,10 +27,14 @@ else raise Ddr::Models::ChecksumInvalid, "The checksum [#{algorithm}]#{checksum} is not valid for datastream #{version_info}." end end + def version_history + versions.map(&:profile) + end + def version_uri # E.g., info:fedora/duke:1/content/content.0 ["info:fedora", pid, dsid, dsVersionID].join("/") unless new? end @@ -39,35 +49,39 @@ def content_digest algorithm Ddr::Utils.digest(self.content, algorithm) end - # Returns a list of the external file paths for all versions of the datastream. def file_paths - raise "The `file_paths' method is valid only for external datastreams." unless external? - return Array(file_path) if new? - versions.map(&:file_path).compact + if new? + return Array(file_path) + else + versions.map(&:file_path).compact + end end - # Returns the external file path for the datastream. - # Returns nil if dsLocation is not a file URI. def file_path - raise "The `file_path' method is valid only for external datastreams." unless external? - Ddr::Utils.path_from_uri(dsLocation) if Ddr::Utils.file_uri?(dsLocation) + if external? && dsLocation.present? && dsLocation.start_with?("file:") + Ddr::Utils.path_from_uri(dsLocation) + end end - # Returns the file name of the external file for the datastream. - # See #external_datastream_file_path(ds) def file_name - raise "The `file_name' method is valid only for external datastreams." unless external? - File.basename(file_path) rescue nil + if path = file_path + File.basename(path) + end end # Returns the size of the external file for the datastream. def file_size - raise "The `file_size' method is valid only for external datastreams." unless external? - File.size(file_path) rescue nil + if external? + if path = file_path + File.size(path) + end + else + dsSize + end end # Return default file extension for datastream based on MIME type def default_file_extension mimetypes = MIME::Types[mimeType] @@ -98,9 +112,40 @@ suffix ||= "." + default_file_extension Tempfile.open [prefix, suffix], encoding: Encoding::ASCII_8BIT do |f| f.write(content) f.close yield f + end + end + + private + + def default_notification_payload + { pid: pid, file_id: dsid, control_group: controlGroup } + end + + def delete_notification_payload + default_notification_payload.merge( + profile: profile.dup, + version_history: version_history + ) + end + + def notify_save + ActiveSupport::Notifications.instrument( + Ddr::Datastreams::SAVE, + default_notification_payload.merge(attributes_changed: changes) + ) do |payload| + yield + payload[:profile] = profile.dup + end + end + + def notify_delete + ActiveSupport::Notifications.instrument( + Ddr::Datastreams::DELETE, delete_notification_payload + ) do |payload| + yield end end end end