Class: Moab::StorageObject

Inherits:
Object
  • Object
show all
Defined in:
lib/moab/storage_object.rb

Overview

Note:

Copyright © 2012 by The Board of Trustees of the Leland Stanford Junior University. All rights reserved. See LICENSE for details.

A class to represent a digital object's repository storage location and methods for

  • packaging a bag for ingest of a new object version to the repository

  • ingesting a bag

  • disseminating a bag containing a reconstructed object version

Data Model

  • StorageRepository = represents a digital object repository storage node

    • StorageServices = supports application layer access to the repository's objects, data, and metadata

    • StorageObject = represents a digital object's repository storage location and ingest/dissemination methods

      • StorageObjectVersion [1..*] = represents a version subdirectory within an object's home directory

        • Bagger [1] = utility for creating bagit packages for ingest or dissemination

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(object_id, object_dir, mkpath = false) ⇒ StorageObject


33
34
35
36
37
# File 'lib/moab/storage_object.rb', line 33

def initialize(object_id, object_dir, mkpath=false)
  @digital_object_id = object_id
  @object_pathname = Pathname.new(object_dir)
  initialize_storage if mkpath
end

Instance Attribute Details

#digital_object_idString


23
24
25
# File 'lib/moab/storage_object.rb', line 23

def digital_object_id
  @digital_object_id
end

#object_pathnamePathname


26
27
28
# File 'lib/moab/storage_object.rb', line 26

def object_pathname
  @object_pathname
end

#storage_rootPathname


29
30
31
# File 'lib/moab/storage_object.rb', line 29

def storage_root
  @storage_root
end

Class Method Details

.version_dirname(version_id) ⇒ String

Returns The directory name of the version, relative to the digital object home directory (e.g v0002)


125
126
127
# File 'lib/moab/storage_object.rb', line 125

def self.version_dirname(version_id)
  ("v%04d" % version_id)
end

Instance Method Details

#current_versionStorageObjectVersion


164
165
166
# File 'lib/moab/storage_object.rb', line 164

def current_version
  self.storage_object_version(current_version_id)
end

#current_version_idInteger

Returns The identifier of the latest version of this object, or 0 if no versions exist


155
156
157
158
159
160
161
# File 'lib/moab/storage_object.rb', line 155

def current_version_id
  return @current_version_id unless @current_version_id.nil?
  #@current_version_id = self.version_id_list.last || 0
  list = self.version_id_list
  version_id = list.empty? ? 0 : list.last
  @current_version_id = version_id
end

#deposit_bag_pathnamePathname


56
57
58
# File 'lib/moab/storage_object.rb', line 56

def deposit_bag_pathname
  deposit_home.join(StorageServices.deposit_branch(digital_object_id))
end

#deposit_homePathname


51
52
53
# File 'lib/moab/storage_object.rb', line 51

def deposit_home
  storage_root.join(StorageServices.deposit_trunk)
end

#empty?Boolean


149
150
151
# File 'lib/moab/storage_object.rb', line 149

def empty?
  version_id_list.empty?
end

#exist?Boolean


40
41
42
# File 'lib/moab/storage_object.rb', line 40

def exist?
  @object_pathname.exist?
end

#find_object_version(version_id = nil) ⇒ StorageObjectVersion

Returns The representation of an existing version's storage area


181
182
183
184
185
186
187
188
189
190
191
# File 'lib/moab/storage_object.rb', line 181

def find_object_version(version_id=nil)
  current = current_version_id
  case version_id
    when nil
      StorageObjectVersion.new(self,current)
    when 1..current
      StorageObjectVersion.new(self,version_id)
    else
      raise "Version ID #{version_id} does not exist"
  end
end

#ingest_bag(bag_dir = deposit_bag_pathname)

This method returns an undefined value.

Returns Ingest a new object version contained in a bag into this objects storage area

Examples:


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/moab/storage_object.rb', line 64

def ingest_bag(bag_dir=deposit_bag_pathname)
  bag_dir = Pathname(bag_dir)
  current_version = StorageObjectVersion.new(self,current_version_id)
  current_inventory = current_version.file_inventory('version')
  new_version = StorageObjectVersion.new(self,current_version_id + 1)
  if FileInventory.xml_pathname_exist?(bag_dir,'version')
    new_inventory = FileInventory.read_xml_file(bag_dir,'version')
  elsif current_version.version_id == 0
    new_inventory = versionize_bag(bag_dir,current_version,new_version)
  end
  validate_new_inventory(new_inventory)
  new_version.ingest_bag_data(bag_dir)
  new_version.update_catalog(current_version.signature_catalog,new_inventory)
  new_version.generate_differences_report(current_inventory,new_inventory)
  new_version.generate_manifest_inventory
  new_version
end

#initialize_storage

This method returns an undefined value.

Returns Create the directory for the digital object home unless it already exists


46
47
48
# File 'lib/moab/storage_object.rb', line 46

def initialize_storage
    @object_pathname.mkpath
end

#reconstruct_version(version_id, bag_dir)

This method returns an undefined value.

Returns Reconstruct an object version and package it in a bag for dissemination

Examples:


106
107
108
109
110
111
112
# File 'lib/moab/storage_object.rb', line 106

def reconstruct_version(version_id, bag_dir)
  storage_version = StorageObjectVersion.new(self,version_id)
  version_inventory = storage_version.file_inventory('version')
  signature_catalog = storage_version.signature_catalog
  bagger = Bagger.new(version_inventory, signature_catalog, bag_dir)
  bagger.fill_bag(:reconstructor,@object_pathname)
end

#restore_object(recovery_path) ⇒ Boolean


219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/moab/storage_object.rb', line 219

def restore_object(recovery_path)
  timestamp = Time.now
  recovery_object = StorageObject.new(@digital_object_id, recovery_path, mkpath=false)
  recovery_object.versions.each do |recovery_version|
    version_id = recovery_version.version_id
    storage_version = self.storage_object_version(version_id)
    # rename/save the original
    storage_version.deactivate(timestamp)
    # copy the recovered version into place
    FileUtils.cp_r(recovery_version.version_pathname.to_s,storage_version.version_pathname.to_s)
  end
  self
end

#storage_filepath(catalog_filepath) ⇒ Pathname

Returns The absolute storage path of the file, including the object's home directory


116
117
118
119
120
# File 'lib/moab/storage_object.rb', line 116

def storage_filepath(catalog_filepath)
  storage_filepath = @object_pathname.join(catalog_filepath)
  raise FileNotFoundException, "#{catalog_filepath} missing from storage location #{storage_filepath}" unless storage_filepath.exist?
  storage_filepath
end

#storage_object_version(version_id) ⇒ StorageObjectVersion

  • Version 0 is a special case used to generate empty manifests

  • Current version + 1 is used for creation of a new version


198
199
200
201
202
203
204
# File 'lib/moab/storage_object.rb', line 198

def storage_object_version(version_id)
  if version_id
    StorageObjectVersion.new(self,version_id)
  else
    raise "Version ID not specified"
  end
end

#validate_new_inventory(version_inventory) ⇒ Boolean

Returns Tests whether the new version number is one higher than the current version number


171
172
173
174
175
176
# File 'lib/moab/storage_object.rb', line 171

def validate_new_inventory(version_inventory)
  if version_inventory.version_id != (current_version_id + 1)
    raise "version mismatch - current: #{current_version_id} new: #{version_inventory.version_id}"
  end
  true
end

#verify_object_storageVerificationResult


207
208
209
210
211
212
213
214
215
# File 'lib/moab/storage_object.rb', line 207

def verify_object_storage
  result = VerificationResult.new(digital_object_id)
  self.version_list.each do |version|
    result.subentities << version.verify_version_storage
  end
  result.subentities << current_version.verify_signature_catalog
  result.verified = result.subentities.all?{|entity| entity.verified}
  result
end

#version_id_listArray<Integer>


130
131
132
133
134
135
136
137
138
139
140
# File 'lib/moab/storage_object.rb', line 130

def version_id_list
  list = Array.new
  return list unless @object_pathname.exist?
  @object_pathname.children.each do |dirname|
    vnum = dirname.basename.to_s
    if vnum.match /^v(\d+)$/
      list << vnum[1..-1].to_i
    end
  end
  list.sort
end

#version_listArray<StorageObjectVersion> Also known as: versions


143
144
145
# File 'lib/moab/storage_object.rb', line 143

def version_list
  version_id_list.collect{|id| self.storage_object_version(id)}
end

#versionize_bag(bag_dir, current_version, new_version) ⇒ FileInventory

Returns The file inventory of the specified type for this version


87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/moab/storage_object.rb', line 87

def versionize_bag(bag_dir,current_version,new_version)
  new_inventory = FileInventory.new(
      :type=>'version',
      :digital_object_id=>@digital_object_id,
      :version_id=>new_version.version_id,
      :inventory_datetime => Time.now
  )
  new_inventory.inventory_from_bagit_bag(bag_dir)
  new_inventory.write_xml_file(bag_dir)
  version_additions = current_version.signature_catalog.version_additions(new_inventory)
  version_additions.write_xml_file(bag_dir)
  new_inventory
end