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, :createdDate => :objCreateDate }
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



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

def initialize(pid, repository = nil, options = {})
  run_callbacks :initialize 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.



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

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

Parameters:

Raises:



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

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



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



121
122
123
124
125
126
127
# File 'lib/rubydora/digital_object.rb', line 121

def asOfDateTime(asOfDateTime = nil)
  if asOfDateTime.nil?
    return @asOfDateTime
  end

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

#asOfDateTime=(val) ⇒ Object



129
130
131
# File 'lib/rubydora/digital_object.rb', line 129

def asOfDateTime=(val)
  @asOfDateTime = val
end

#audit_trailObject



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

def audit_trail
  @audit_trail ||= repository.audit_trail(self.pid)
end

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

List of datastreams

Returns:



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/rubydora/digital_object.rb', line 150

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

    begin
      options = { :pid => pid, :profiles => 'true' }
      options[:asOfDateTime] = asOfDateTime if asOfDateTime
      datastreams_xml = repository.datastreams(options)
      # pre-3.6, the profiles parm will be ignored
      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
      # post-3.6, full ds profiles will be returned
      doc.xpath('//access:datastreamProfile', {'access' => "http://www.fedora.info/definitions/1/0/access/"}).each do |ds|
        # n.b. that the dsID attribute has a different name in the profile response
        h[ds['dsID']] = datastream_object_for(ds['dsID'], {:profile => ProfileParser.hash_datastream_profile_node(ds)})
      end
    rescue RestClient::ResourceNotFound
    end

    h
  end
end

#deleteRubydora::DigitalObject

Purge the object from Fedora

Returns:



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

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



178
179
180
# File 'lib/rubydora/digital_object.rb', line 178

def fetch(dsid)
  datastreams[dsid]
end

#new_record?Boolean Also known as: new?

Does this object already exist?

Returns:

  • (Boolean)


116
117
118
# File 'lib/rubydora/digital_object.rb', line 116

def new_record?
  self.profile.empty?
end

#profileHash

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

Returns:

  • (Hash)

    see Fedora #getObject documentation for keys



135
136
137
138
139
140
# File 'lib/rubydora/digital_object.rb', line 135

def profile
  @profile ||= begin
    @new = false
    repository.object_profile(pid, asOfDateTime)
  end.freeze
end

#repositoryRubydora::Repository

repository reference from the digital object



230
231
232
# File 'lib/rubydora/digital_object.rb', line 230

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 ‘:changed?` datastreams that already exist new datastreams must be directly saved

Returns:



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/rubydora/digital_object.rb', line 190

def save
  check_if_read_only
  mod_time = nil
  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
      unless p.empty?
        mod_time = repository.modify_object p.merge(:pid => pid)
        clear_changes_information
      end
    end
  end
  mod_time = save_datastreams(mod_time)
  # mod_time will be nil on new objects with no ds changes
  unless mod_time.nil?
    self.lastModifiedDate = mod_time
    clear_attribute_changes(['lastModifiedDate'])
  end
  self
end

#state=(val) ⇒ Object

Raises:

  • (ArgumentError)


42
43
44
45
46
# File 'lib/rubydora/digital_object.rb', line 42

def state=(val)
  raise ArgumentError, "Allowed values for state are 'I', 'A' and 'D'. You provided '#{val}'" unless ['I', 'A', 'D'].include?(val)
  state_will_change! unless val == state
  @state = val
end

#uriObject Also known as: fqpid

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



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

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

#versionsObject



142
143
144
145
146
# File 'lib/rubydora/digital_object.rb', line 142

def versions
  repository.versions_for_object(pid).map do |changeDate|
    self.class.new pid, repository, :asOfDateTime => changeDate
  end
end