Class: Rubydora::DigitalObject

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Callbacks
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



70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/rubydora/digital_object.rb', line 70

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.



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:



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

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:



46
47
48
# File 'lib/rubydora/digital_object.rb', line 46

def self.find pid, repository = nil, options = {}
  self.new pid, repository, options
end

Instance Method Details

#asOfDateTime(asOfDateTime = nil) ⇒ Object



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

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

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

#asOfDateTime=(val) ⇒ Object



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

def asOfDateTime= val
  @asOfDateTime = val
end

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

List of datastreams

Returns:



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

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:



205
206
207
208
209
210
211
212
213
214
215
# File 'lib/rubydora/digital_object.rb', line 205

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



175
176
177
# File 'lib/rubydora/digital_object.rb', line 175

def fetch dsid
  datastreams[dsid]
end

#new?Boolean

Does this object already exist?

Returns:

  • (Boolean)


93
94
95
96
# File 'lib/rubydora/digital_object.rb', line 93

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



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/rubydora/digital_object.rb', line 112

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
    h.select { |key, value| value.length == 1 }.each do |key, value|
      next if key == "objModels"
      h[key] = value.first
    end
    @new = false

    h
  rescue Exception => e
    {}
  end.freeze
end

#repositoryRubydora::Repository

repository reference from the digital object



219
220
221
# File 'lib/rubydora/digital_object.rb', line 219

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:



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/rubydora/digital_object.rb', line 187

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



85
86
87
88
# File 'lib/rubydora/digital_object.rb', line 85

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

#versionsObject



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

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