Class: OcflTools::OcflInventory

Inherits:
OcflObject show all
Defined in:
lib/ocfl_tools/ocfl_inventory.rb

Overview

create and manipulate an OCFL inventory file.

Direct Known Subclasses

OcflDeposit

Instance Attribute Summary

Attributes inherited from OcflObject

#contentDirectory, #digestAlgorithm, #fixity, #head, #id, #manifest, #type, #versions

Instance Method Summary collapse

Methods inherited from OcflObject

#add_file, #copy_file, #create_version_hash, #delete_file, #get_current_files, #get_digest, #get_files, #get_state, #get_version, #get_version_created, #get_version_message, #get_version_user, #initialize, #move_file, #set_head_from_version, #set_state, #set_version, #set_version_created, #set_version_message, #set_version_user, #update_file, #update_fixity, #update_manifest, #version_id_list

Constructor Details

This class inherits a constructor from OcflTools::OcflObject

Instance Method Details

#from_file(file) ⇒ self

Reads in a file, parses the JSON and ingests it into an OcflTools::OcflInventory

Parameters:

  • file (Pathname)

    fully-qualified filepath to a valid OCFL inventory.json.

Returns:

  • (self)


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/ocfl_tools/ocfl_inventory.rb', line 70

def from_file(file)
  import_hash = read_json(file)

  # REQUIRED keys; raise exception if not found.
  e216_errors = []
  e217_errors = []
  error_hash  = {}
  [ 'id', 'head', 'type', 'digestAlgorithm', 'manifest', 'versions' ].each do | key |
    unless import_hash.key?(key)
      e216_errors << "Required key #{key} not found in #{file}"
      error_hash["E216"] = e216_errors # we'll keep updating this value as new errors are recorded.
    end
    if import_hash.key?(key) && import_hash[key].empty?
      # If the key exists but it's empty, that's also a problem!
      e217_errors << "Required key #{key} in #{file} must contain a value"
      error_hash["E217"] = e217_errors
    end
  end
  # Raise a problem if we have anything in error_hash.
  if error_hash.size > 0
    raise OcflTools::Errors::ValidationError, details: error_hash
  end

  # The actual values of these keys may be hot garbage, but it's not ocfl_inventory's place to check.

  @id               = import_hash['id']
  @head             = import_hash['head']
  @type             = import_hash['type']
  @digestAlgorithm  = import_hash['digestAlgorithm']
  @manifest         = import_hash['manifest']
  @versions         = import_hash['versions']
  # Optional keys - contentDirectory and fixity block.
  @fixity           = import_hash['fixity'] if import_hash.key?('fixity')
  @contentDirectory = import_hash['contentDirectory'] if import_hash.key?('contentDirectory')

  self
end

#read_json(file) ⇒ Hash

Reads a file in from disk and parses the JSON within.

Parameters:

  • file (Pathname)

    resolvable path to alleged inventory.json.

Returns:

  • (Hash)

    of JSON keys & values.



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/ocfl_tools/ocfl_inventory.rb', line 53

def read_json(file)
  begin
    JSON.parse(File.read(file))
  rescue JSON::ParserError
    raise OcflTools::Errors::ValidationError, details: { "E211" => ["#{file} is not valid JSON."] }
  rescue Errno::ENOENT
    # raise OcflTools::Errors::Error215, "expected inventory file #{file} not found!"
    raise OcflTools::Errors::ValidationError, details: { "E215" => ["expected inventory file #{file} not found!"] }
  # rescue Errno::EACCES Don't think we need to explicitly raise file permissions; let StdErr take it.
  rescue StandardError => e
    raise "An unknown error occured reading file #{file}: #{e}" # catch/encapsulate any FileIO issues
  end
end

#serializeJSON

serializes all versions of the object to JSON. for writing to a storage layer.

Returns:

  • (JSON)

    complete OCFL object in serialized JSON format, suitable



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/ocfl_tools/ocfl_inventory.rb', line 9

def serialize
  output_hash = {}

  set_head_version # We're about to make an OCFL. At least pretend it'll pass validation.

  # If you've not set type by now, set it to the site default.
  @type ||= OcflTools.config.content_type

  output_hash['id']               = @id
  output_hash['head']             = @head
  output_hash['type']             = @type
  output_hash['digestAlgorithm']  = @digestAlgorithm
  unless @contentDirectory.empty?
    output_hash['contentDirectory'] = @contentDirectory
  end
  output_hash['manifest']         = @manifest
  output_hash['versions']         = @versions
  # optional
  output_hash['fixity']           = @fixity unless @fixity.empty?

  JSON.pretty_generate(output_hash)
end

#set_head_versionString

Sets @head to highest version found in object.

Returns:

  • (String)

    current version name.



34
35
36
# File 'lib/ocfl_tools/ocfl_inventory.rb', line 34

def set_head_version
  set_head_from_version(version_id_list.max)
end

#to_file(directory) ⇒ Object

Writes inventory file and inventory sidecar digest file to a directory.

Parameters:

  • directory (String)

    resolvable directory to write inventory.json to.



40
41
42
43
44
45
46
47
48
# File 'lib/ocfl_tools/ocfl_inventory.rb', line 40

def to_file(directory)
  inventory = File.new("#{directory}/inventory.json", 'w+')
  inventory.syswrite(serialize)

  checksum = OcflTools::Utils.generate_file_digest(inventory.path, @digestAlgorithm)

  inventory_digest = File.new("#{inventory.path}.#{@digestAlgorithm}", 'w+')
  inventory_digest.syswrite("#{checksum} inventory.json")
end