Class: Rubydora::Datastream
- Inherits:
-
Object
- Object
- Rubydora::Datastream
- Extended by:
- ActiveModel::Callbacks
- Includes:
- ActiveModel::Dirty
- Defined in:
- lib/rubydora/datastream.rb
Overview
This class represents a Fedora datastream object and provides helper methods for creating and manipulating them.
Constant Summary collapse
- DS_ATTRIBUTES =
mapping datastream attributes (and api parameters) to datastream profile names
{:controlGroup => :dsControlGroup, :dsLocation => :dsLocation, :altIDs => nil, :dsLabel => :dsLabel, :versionable => :dsVersionable, :dsState => :dsState, :formatURI => :dsFormatURI, :checksumType => :dsChecksumType, :checksum => :dsChecksum, :mimeType => :dsMIME, :logMessage => nil, :ignoreContent => nil, :lastModifiedDate => nil, :content => nil, :asOfDateTime => nil}
- DS_DEFAULT_ATTRIBUTES =
{ :controlGroup => 'M', :dsState => 'A', :versionable => true }
- DS_READONLY_ATTRIBUTES =
[ :dsCreateDate , :dsSize, :dsVersionID ]
Instance Attribute Summary collapse
-
#digital_object ⇒ Object
readonly
Returns the value of attribute digital_object.
-
#dsid ⇒ Object
readonly
Returns the value of attribute dsid.
Class Method Summary collapse
Instance Method Summary collapse
- #asOfDateTime(asOfDateTime = nil) ⇒ Object
- #changed? ⇒ Boolean
-
#content ⇒ Object
(also: #read)
This method is overridden in ActiveFedora, so we didn’t.
-
#content=(new_content) ⇒ String or IO
Set the content of the datastream.
- #content_changed? ⇒ Boolean
-
#create ⇒ Rubydora::Datastream
Add datastream to Fedora.
- #datastream_content ⇒ Object
- #datastream_will_change! ⇒ Object
- #default_attributes ⇒ Object
- #default_attributes=(attributes) ⇒ Object
-
#delete ⇒ Rubydora::Datastream
Purge the datastream from Fedora.
- #has_content? ⇒ Boolean
-
#initialize(digital_object, dsid, options = {}, default_instance_attributes = {}) ⇒ Datastream
constructor
Initialize a Rubydora::Datastream object, which may or may not already exist in the datastore.
-
#local_or_remote_content(ensure_fetch = true) ⇒ String
Retrieve the content of the datastream (and cache it).
-
#new? ⇒ Boolean
Does this datastream already exist?.
-
#pid ⇒ Object
Helper method to get digital object pid.
-
#profile(opts = {}) ⇒ Hash
Retrieve the datastream profile as a hash (and cache it).
- #profile=(profile_xml) ⇒ Object
- #profile_xml(opts = {}) ⇒ Object
- #profile_xml_to_hash(profile_xml) ⇒ Object
-
#save ⇒ Rubydora::Datastream
Modify or save the datastream.
-
#url ⇒ String
Get the URL for the datastream content.
- #versions ⇒ Object
Constructor Details
#initialize(digital_object, dsid, options = {}, default_instance_attributes = {}) ⇒ Datastream
Initialize a Rubydora::Datastream object, which may or may not already exist in the datastore.
Provides ‘after_initialize` callback for extensions
102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/rubydora/datastream.rb', line 102 def initialize digital_object, dsid, = {}, default_instance_attributes = {} _run_initialize_callbacks do @digital_object = digital_object @dsid = dsid @options = @default_attributes = default_attributes.merge(default_instance_attributes) .each do |key, value| self.send(:"#{key}=", value) end end end |
Instance Attribute Details
#digital_object ⇒ Object (readonly)
Returns the value of attribute digital_object.
16 17 18 |
# File 'lib/rubydora/datastream.rb', line 16 def digital_object @digital_object end |
#dsid ⇒ Object (readonly)
Returns the value of attribute dsid.
16 17 18 |
# File 'lib/rubydora/datastream.rb', line 16 def dsid @dsid end |
Class Method Details
.default_attributes ⇒ Object
81 82 83 |
# File 'lib/rubydora/datastream.rb', line 81 def self.default_attributes DS_DEFAULT_ATTRIBUTES end |
Instance Method Details
#asOfDateTime(asOfDateTime = nil) ⇒ Object
73 74 75 76 77 78 79 |
# File 'lib/rubydora/datastream.rb', line 73 def asOfDateTime asOfDateTime = nil if asOfDateTime == nil return @asOfDateTime end return self.class.new(@digital_object, @dsid, @options.merge(:asOfDateTime => asOfDateTime)) end |
#changed? ⇒ Boolean
199 200 201 |
# File 'lib/rubydora/datastream.rb', line 199 def changed? super || content_changed? end |
#content ⇒ Object Also known as: read
This method is overridden in ActiveFedora, so we didn’t
126 127 128 |
# File 'lib/rubydora/datastream.rb', line 126 def content local_or_remote_content(true) end |
#content=(new_content) ⇒ String or IO
Set the content of the datastream
174 175 176 177 |
# File 'lib/rubydora/datastream.rb', line 174 def content= new_content raise "Can't change values on older versions" if @asOfDateTime @content = new_content end |
#content_changed? ⇒ Boolean
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/rubydora/datastream.rb', line 179 def content_changed? return false if ['E','R'].include? controlGroup return true if new? and !local_or_remote_content(false).blank? # new datastreams must have content if controlGroup == "X" if self.eager_load_datastream_content return !EquivalentXml.equivalent?(Nokogiri::XML(local_or_remote_content(false)), Nokogiri::XML(datastream_content)) else return !EquivalentXml.equivalent?(Nokogiri::XML(local_or_remote_content(false)), Nokogiri::XML(@datastream_content)) end else if self.eager_load_datastream_content return local_or_remote_content(false) != datastream_content else return local_or_remote_content(false) != @datastream_content end end super end |
#create ⇒ Rubydora::Datastream
Add datastream to Fedora
288 289 290 291 292 293 294 295 |
# File 'lib/rubydora/datastream.rb', line 288 def create check_if_read_only run_callbacks :create do repository.add_datastream to_api_params.merge({ :pid => pid, :dsid => dsid, :content => content }) reset_profile_attributes self.class.new(digital_object, dsid, @options) end end |
#datastream_content ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/rubydora/datastream.rb', line 151 def datastream_content return nil if new? @datastream_content ||=begin = { :pid => pid, :dsid => dsid } [:asOfDateTime] = asOfDateTime if asOfDateTime repository.datastream_dissemination rescue RestClient::ResourceNotFound end end |
#datastream_will_change! ⇒ Object
322 323 324 |
# File 'lib/rubydora/datastream.rb', line 322 def datastream_will_change! attribute_will_change! :profile end |
#default_attributes ⇒ Object
85 86 87 |
# File 'lib/rubydora/datastream.rb', line 85 def default_attributes @default_attributes ||= self.class.default_attributes end |
#default_attributes=(attributes) ⇒ Object
89 90 91 |
# File 'lib/rubydora/datastream.rb', line 89 def default_attributes= attributes @default_attributes = default_attributes.merge attributes end |
#delete ⇒ Rubydora::Datastream
Purge the datastream from Fedora
312 313 314 315 316 317 318 319 320 |
# File 'lib/rubydora/datastream.rb', line 312 def delete check_if_read_only run_callbacks :destroy do repository.purge_datastream(:pid => pid, :dsid => dsid) unless self.new? digital_object.datastreams.delete(dsid) reset_profile_attributes self end end |
#has_content? ⇒ Boolean
203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/rubydora/datastream.rb', line 203 def has_content? # persisted objects are required to have content return true unless new? # type E and R objects should have content. return !dsLocation.blank? if ['E','R'].include? controlGroup # if we've set content, then we have content. # return true if instance_variable_defined? :@content behaves_like_io?(@content) || !content.blank? end |
#local_or_remote_content(ensure_fetch = true) ⇒ String
Retrieve the content of the datastream (and cache it)
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/rubydora/datastream.rb', line 133 def local_or_remote_content(ensure_fetch = true) return @content if new? @content ||= ensure_fetch ? datastream_content : @datastream_content if behaves_like_io?(@content) begin @content.rewind @content.read ensure @content.rewind end else @content end end |
#new? ⇒ Boolean
Does this datastream already exist?
121 122 123 |
# File 'lib/rubydora/datastream.rb', line 121 def new? digital_object.nil? || digital_object.new? || profile_xml.blank? end |
#pid ⇒ Object
Helper method to get digital object pid
115 116 117 |
# File 'lib/rubydora/datastream.rb', line 115 def pid digital_object.pid end |
#profile(opts = {}) ⇒ Hash
Retrieve the datastream profile as a hash (and cache it)
220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/rubydora/datastream.rb', line 220 def profile opts= {} if @profile && !(opts[:validateChecksum] && !@profile.has_key?('dsChecksumValid')) ## Force a recheck of the profile if they've passed :validateChecksum and we don't have dsChecksumValid return @profile end return @profile = {} unless digital_object.respond_to? :repository @profile = begin xml = profile_xml(opts) (self.profile_xml_to_hash(xml) unless xml.blank?) || {} end end |
#profile=(profile_xml) ⇒ Object
253 254 255 |
# File 'lib/rubydora/datastream.rb', line 253 def profile= profile_xml @profile = self.profile_xml_to_hash(profile_xml) end |
#profile_xml(opts = {}) ⇒ Object
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/rubydora/datastream.rb', line 235 def profile_xml opts = {} @profile_xml = nil unless opts.empty? @profile_xml ||= begin = { :pid => pid, :dsid => dsid } .merge!(opts) [:asOfDateTime] = asOfDateTime if asOfDateTime [:validateChecksum] = true if repository.config[:validateChecksum] repository.datastream() rescue RestClient::Unauthorized => e raise e rescue RestClient::ResourceNotFound # the datastream is new '' end end |
#profile_xml_to_hash(profile_xml) ⇒ Object
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/rubydora/datastream.rb', line 257 def profile_xml_to_hash profile_xml profile_xml.gsub! '<datastreamProfile', '<datastreamProfile xmlns="http://www.fedora.info/definitions/1/0/management/"' unless profile_xml =~ /xmlns=/ doc = Nokogiri::XML(profile_xml) h = doc.xpath('/management:datastreamProfile/*', {'management' => "http://www.fedora.info/definitions/1/0/management/"} ).inject({}) do |sum, node| sum[node.name] ||= [] sum[node.name] << node.text sum end.reject { |key, values| values.empty? } h.select { |key, values| values.length == 1 }.each do |key, values| h[key] = values.reject { |x| x.empty? }.first end h['dsSize'] &&= h['dsSize'].to_i rescue h['dsSize'] h['dsCreateDate'] &&= Time.parse(h['dsCreateDate']) rescue h['dsCreateDate'] h['dsChecksumValid'] &&= h['dsChecksumValid'] == 'true' h['dsVersionable'] &&= h['dsVersionable'] == 'true' h end |
#save ⇒ Rubydora::Datastream
Modify or save the datastream
299 300 301 302 303 304 305 306 307 308 |
# File 'lib/rubydora/datastream.rb', line 299 def save check_if_read_only run_callbacks :save do raise RubydoraError.new("Unable to save #{self.inspect} without content") unless has_content? return create if new? repository.modify_datastream to_api_params.merge({ :pid => pid, :dsid => dsid }) reset_profile_attributes self.class.new(digital_object, dsid, @options) end end |
#url ⇒ String
Get the URL for the datastream content
165 166 167 168 169 |
# File 'lib/rubydora/datastream.rb', line 165 def url = { } [:asOfDateTime] = asOfDateTime if asOfDateTime repository.datastream_url(pid, dsid, ) + "/content" end |
#versions ⇒ Object
276 277 278 279 280 281 282 283 284 |
# File 'lib/rubydora/datastream.rb', line 276 def versions versions_xml = repository.datastream_versions(:pid => pid, :dsid => dsid) return [] if versions_xml.nil? versions_xml.gsub! '<datastreamProfile', '<datastreamProfile xmlns="http://www.fedora.info/definitions/1/0/management/"' unless versions_xml =~ /xmlns=/ doc = Nokogiri::XML(versions_xml) doc.xpath('//management:datastreamProfile', {'management' => "http://www.fedora.info/definitions/1/0/management/"} ).map do |ds| self.class.new @digital_object, @dsid, :profile => ds.to_s, :asOfDateTime => ds.xpath('management:dsCreateDate', 'management' => "http://www.fedora.info/definitions/1/0/management/").text end end |