Class: Rubydora::DigitalObject

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Callbacks, Deprecation
Includes:
ActiveModel::Dirty, ExtensionParameters, ModelsMixin, RelationshipsMixin
Defined in:
lib/rubydora/digital_object.rb

Overview

This class represents a Fedora object and provides helpers for managing attributes, datastreams, and relationships.

Using the extension framework, implementors may provide additional functionality to this base implementation.

Constant Summary collapse

OBJ_ATTRIBUTES =

mapping object parameters to profile elements

{:state => :objState, :ownerId => :objOwnerId, :label => :objLabel, :logMessage => nil, :lastModifiedDate => :objLastModDate }
OBJ_DEFAULT_ATTRIBUTES =
{ }

Constants included from RelationshipsMixin

RelationshipsMixin::RELS_EXT

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from RelationshipsMixin

#add_relationship, included, #purge_relationship, #relationship, #relationship_changed, #relationships

Methods included from ModelsMixin

#models, #models=

Methods included from ExtensionParameters

#apply_extensions, included

Constructor Details

#initialize(pid, repository = nil, options = {}) ⇒ DigitalObject

Initialize a Rubydora::DigitalObject, which may or may not already exist in the data store.

Provides ‘after_initialize` callback for extensions

Parameters:

  • pid (String)
  • repository (Rubydora::Repository) (defaults to: nil)

    context

  • options (Hash) (defaults to: {})

    default attribute values (used esp. for creating new datastreams



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/rubydora/digital_object.rb', line 90

def initialize pid, repository = nil, options = {}
  _run_initialize_callbacks do
    self.pid = pid
    @repository = repository
    @new = true
    @options = options

    options.each do |key, value|
      self.send(:"#{key}=", value)
    end
  end
end

Instance Attribute Details

#pidObject

Returns the value of attribute pid.



24
25
26
# File 'lib/rubydora/digital_object.rb', line 24

def pid
  @pid
end

Class Method Details

.create(pid, options = {}, repository = nil) ⇒ Object

create a new fedora object (see also DigitalObject#save)

Parameters:



74
75
76
77
78
79
# File 'lib/rubydora/digital_object.rb', line 74

def self.create pid, options = {}, repository = nil
  repository ||= Rubydora.repository
  assigned_pid = repository.ingest(options.merge(:pid => pid))

  self.new assigned_pid, repository
end

.find(pid, repository = nil, options = {}) ⇒ Object

find an existing fedora object TODO: raise an error if the object does not yet exist

Parameters:



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/rubydora/digital_object.rb', line 50

def self.find pid, repository = nil, options = {}
  obj = self.new pid, repository, options
  if obj.new?
    Deprecation.warn(Rubydora::DigitalObject, "DigitalObject.find called 
      for an object that doesn't exist. In #{Rubydora::DigitalObject.deprecation_horizon},
      this behavior will raise an exception. Use
      DigitalObject.new or DigitalObject.find_or_initialize instead.")
  end

  obj
end

.find_or_initialize(*args) ⇒ Object

find or initialize a Fedora object

Parameters:

  • pid (String)
  • repository (Rubydora::Repository)

    context

  • options (Hash)

    default attribute values (used esp. for creating new datastreams



66
67
68
# File 'lib/rubydora/digital_object.rb', line 66

def self.find_or_initialize *args
  self.new *args
end

Instance Method Details

#asOfDateTime(asOfDateTime = nil) ⇒ Object



118
119
120
121
122
123
124
# File 'lib/rubydora/digital_object.rb', line 118

def asOfDateTime asOfDateTime = nil
  if asOfDateTime == nil
    return @asOfDateTime
  end

  return self.class.new(pid, @repository, @options.merge(:asOfDateTime => asOfDateTime))
end

#asOfDateTime=(val) ⇒ Object



126
127
128
# File 'lib/rubydora/digital_object.rb', line 126

def asOfDateTime= val
  @asOfDateTime = val
end

#datastreamsArray<Rubydora::Datastream> Also known as: datastream

List of datastreams

Returns:



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/rubydora/digital_object.rb', line 174

def datastreams
  @datastreams ||= begin
    h = Hash.new { |h,k| h[k] = datastream_object_for(k) }                

    begin
      options = { :pid => pid }
      options[:asOfDateTime] = asOfDateTime if asOfDateTime
      datastreams_xml = repository.datastreams(options)
      datastreams_xml.gsub! '<objectDatastreams', '<objectDatastreams xmlns="http://www.fedora.info/definitions/1/0/access/"' unless datastreams_xml =~ /xmlns=/
      doc = Nokogiri::XML(datastreams_xml)
      doc.xpath('//access:datastream', {'access' => "http://www.fedora.info/definitions/1/0/access/"}).each do |ds| 
        h[ds['dsid']] = datastream_object_for ds['dsid'] 
      end
    rescue RestClient::ResourceNotFound
    end

    h
  end
end

#deleteRubydora::DigitalObject

Purge the object from Fedora

Returns:



226
227
228
229
230
231
232
233
234
235
236
# File 'lib/rubydora/digital_object.rb', line 226

def delete
  check_if_read_only
  my_pid = pid
  run_callbacks :destroy do
    @datastreams = nil
    @profile = nil
    @pid = nil
    nil
  end
  repository.purge_object(:pid => my_pid) ##This can have a meaningful exception, don't put it in the callback
end

#fetch(dsid) ⇒ Object Also known as: []

provide an hash-like way to access datastreams



196
197
198
# File 'lib/rubydora/digital_object.rb', line 196

def fetch dsid
  datastreams[dsid]
end

#new?Boolean

Does this object already exist?

Returns:

  • (Boolean)


113
114
115
116
# File 'lib/rubydora/digital_object.rb', line 113

def new?
  self.profile  ### Make sure we've checked the repository at least once
  @new
end

#profileHash

Retrieve the object profile as a hash (and cache it)

Returns:

  • (Hash)

    see Fedora #getObject documentation for keys



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/rubydora/digital_object.rb', line 132

def profile
  @profile ||= begin
    options = { :pid => pid }
    options[:asOfDateTime] = asOfDateTime if asOfDateTime
    profile_xml = repository.object(options)
    profile_xml.gsub! '<objectProfile', '<objectProfile xmlns="http://www.fedora.info/definitions/1/0/access/"' unless profile_xml =~ /xmlns=/
    doc = Nokogiri::XML(profile_xml)
    h = doc.xpath('/access:objectProfile/*', {'access' => "http://www.fedora.info/definitions/1/0/access/"} ).inject({}) do |sum, node|
                 sum[node.name] ||= []
                 sum[node.name] << node.text

                 if node.name == "objModels"
                   sum[node.name] = node.xpath('access:model', {'access' => "http://www.fedora.info/definitions/1/0/access/"}).map { |x| x.text }
                 end

                 sum
               end.reject { |key, values| values.empty? }

    h.select { |key, values| values.length == 1 }.each do |key, values|
      next if key == "objModels"
      h[key] = values.reject { |x| x.empty? }.first
    end
    @new = false

    h
  rescue RestClient::ResourceNotFound => e
    {}
  end.freeze
end

#repositoryRubydora::Repository

repository reference from the digital object



240
241
242
# File 'lib/rubydora/digital_object.rb', line 240

def repository
  @repository ||= Rubydora.repository
end

#saveRubydora::DigitalObject

persist the object to Fedora, either as a new object by modifing the existing object

also will save all ‘:dirty?` datastreams that already exist new datastreams must be directly saved

Returns:



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/rubydora/digital_object.rb', line 208

def save
  check_if_read_only
  run_callbacks :save do
    if self.new?
      self.pid = repository.ingest to_api_params.merge(:pid => pid)
      @profile = nil #will cause a reload with updated data
    else                       
      p = to_api_params
      repository.modify_object p.merge(:pid => pid) unless p.empty?
    end
  end

  self.datastreams.select { |dsid, ds| ds.changed? }.each { |dsid, ds| ds.save }
  self
end

#uriObject Also known as: fqpid

Return a full uri pid (for use in relations, etc



105
106
107
108
# File 'lib/rubydora/digital_object.rb', line 105

def uri
  return pid if pid =~ /.+\/.+/
  "info:fedora/#{pid}"
end

#versionsObject



162
163
164
165
166
167
168
169
# File 'lib/rubydora/digital_object.rb', line 162

def versions
  versions_xml = repository.object_versions(:pid => pid)
  versions_xml.gsub! '<fedoraObjectHistory', '<fedoraObjectHistory xmlns="http://www.fedora.info/definitions/1/0/access/"' unless versions_xml =~ /xmlns=/
  doc = Nokogiri::XML(versions_xml)
  doc.xpath('//access:objectChangeDate', {'access' => 'http://www.fedora.info/definitions/1/0/access/' } ).map do |changeDate|
    self.class.new pid, repository, :asOfDateTime => changeDate.text 
  end
end