Class: Rubydora::DigitalObject

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Callbacks, Deprecation
Includes:
ActiveModel::Dirty, AuditTrail, 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 AuditTrail

#audit_trail

Methods included from RelationshipsMixin

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

Methods included from ModelsMixin

#models, #models=

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



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/rubydora/digital_object.rb', line 85

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

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

Instance Attribute Details

#pidObject

Returns the value of attribute pid.



21
22
23
# File 'lib/rubydora/digital_object.rb', line 21

def pid
  @pid
end

Class Method Details

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

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

Parameters:



69
70
71
72
73
74
# File 'lib/rubydora/digital_object.rb', line 69

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

Parameters:

Raises:



48
49
50
51
52
53
54
55
# File 'lib/rubydora/digital_object.rb', line 48

def self.find pid, repository = nil, options = {}
  obj = self.new pid, repository, options
  if obj.new?
    raise Rubydora::RecordNotFound, "DigitalObject.find called for an object that doesn't exist"
  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



61
62
63
# File 'lib/rubydora/digital_object.rb', line 61

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

Instance Method Details

#asOfDateTime(asOfDateTime = nil) ⇒ Object



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

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

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

#asOfDateTime=(val) ⇒ Object



119
120
121
# File 'lib/rubydora/digital_object.rb', line 119

def asOfDateTime= val
  @asOfDateTime = val
end

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

List of datastreams

Returns:



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

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:



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

def delete
  check_if_read_only
  my_pid = pid
  run_callbacks :destroy do
    @datastreams = nil
    @profile = nil
    @profile_xml = 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



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

def fetch dsid
  datastreams[dsid]
end

#new?Boolean

Does this object already exist?

Returns:

  • (Boolean)


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

def new?
  self.profile_xml.blank?
end

#profileHash

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

Returns:

  • (Hash)

    see Fedora #getObject documentation for keys



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/rubydora/digital_object.rb', line 125

def profile
  return {} if profile_xml.nil?

  @profile ||= begin
    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
  
  end.freeze
end

#profile_xmlObject



153
154
155
156
157
158
159
160
161
# File 'lib/rubydora/digital_object.rb', line 153

def profile_xml
  @profile_xml ||= begin
    options = { :pid => pid }
    options[:asOfDateTime] = asOfDateTime if asOfDateTime
    repository.object(options)
  rescue RestClient::ResourceNotFound => e
    ''
  end
end

#repositoryRubydora::Repository

repository reference from the digital object



243
244
245
# File 'lib/rubydora/digital_object.rb', line 243

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:



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

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
      @profile_xml = nil
    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



99
100
101
102
# File 'lib/rubydora/digital_object.rb', line 99

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

#versionsObject



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

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