Class: Rubydora::DigitalObject

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

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



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

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.



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

def pid
  @pid
end

Class Method Details

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

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

Parameters:



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

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:



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

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



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

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

Instance Method Details

#asOfDateTime(asOfDateTime = nil) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/rubydora/digital_object.rb', line 115

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

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

#asOfDateTime=(val) ⇒ Object



123
124
125
# File 'lib/rubydora/digital_object.rb', line 123

def asOfDateTime= val
  @asOfDateTime = val
end

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

List of datastreams

Returns:



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/rubydora/digital_object.rb', line 179

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:



232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/rubydora/digital_object.rb', line 232

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



201
202
203
# File 'lib/rubydora/digital_object.rb', line 201

def fetch dsid
  datastreams[dsid]
end

#new?Boolean

Does this object already exist?

Returns:

  • (Boolean)


111
112
113
# File 'lib/rubydora/digital_object.rb', line 111

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



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

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



157
158
159
160
161
162
163
164
165
# File 'lib/rubydora/digital_object.rb', line 157

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



247
248
249
# File 'lib/rubydora/digital_object.rb', line 247

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:



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/rubydora/digital_object.rb', line 213

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



103
104
105
106
# File 'lib/rubydora/digital_object.rb', line 103

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

#versionsObject



167
168
169
170
171
172
173
174
# File 'lib/rubydora/digital_object.rb', line 167

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